協程若是不cover異常會出現閃退問題,可是在大批量建立各類協程每次都須要cover會很是難處理,golang 異常處理我不是很熟悉,簡單寫了一個,不知道是否靠譜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) }