协程如果不cover异常会出现闪退问题,但是在大批量创建各种协程每次都需要cover会非常难处理,golang 异常处理我不是很熟悉,简单写了一个,不知道是否靠谱
common
package logger import ( "fmt" "reflect" "runtime" "strings" ) //创建安全的协程 func CreateSafeGo(call func(), errCall func(err interface{})) { go func() { defer SafeGoRecover(errCall) call() }() } func SafeGoRecover(errCall func(err interface{})) { if err := recover(); err != nil { Error("recover error: %v", err) if errCall != nil { errCall(err) } } } func getCaller() string { src := "No Caller" _, file, lineno, ok := runtime.Caller(2) var strim = "src/" //fix # 不是每个前面都有src的,所以可以获取当前 if ok { src = strings.Replace(fmt.Sprintf("%s:%d", stringTrim(file, strim), lineno), "%2e", ".", -1) } return src } //TODO Params //反射实现参数恢复 func SafeGoWithParams(call interface{}, errCall func(err interface{}), params ...interface{}) { go func() { defer SafeGoRecover(errCall) funcValue := reflect.ValueOf(call) var paramsList []reflect.Value for _, v := range params { paramsList = append(paramsList, reflect.ValueOf(v)) } funcValue.Call(paramsList) }() }
package logger import ( "fmt" "testing" "time" ) func TestCreateSafeGo(t *testing.T) { CreateSafeGo(func() { panic("1231") }, func(err interface{}) { Error("asdasd") }) time.Sleep(time.Second) } func TestSafeGoRecover(t *testing.T) { go func() { defer SafeGoRecover(func(err interface{}) { Error("asdasd") }) panic("1231") }() time.Sleep(time.Second) } func TestCreateSafeGoWithParams(t *testing.T) { SafeGoWithParams(func(aa int) { fmt.Println(aa) }, func(err interface{}) { }, 123) time.Sleep(time.Second) }