多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] > [Go语言(golang)新发布的1.13中的Error Wrapping深度分析 ](https://www.flysnow.org/2019/09/06/go1.13-error-wrapping.html) ### 常用错误类型 ``` os.ErrInvalid os.ErrPermission os.ErrExist os.ErrNotExist os.ErrClosed os.ErrNoDeadline // 判断类型 os.IsExist(err) os.IsNotExist(err) os.IsPermission(err) os.IsTimeout(err) os.IsTimeout(err) //使用 _, err := os.Open("/no/such/file") fmt.Println(os.IsNotExist(err)) // "true" ``` ## 更新 error (1.13) ### error 的多层嵌套 ``` e := fmt.Errorf("第一层错误") //等于 errors.New("原始错误e") e = fmt.Errorf("第二层错误%w", e) ``` ### Unwrap 它的功能就是为了获得被嵌套的error ``` e := fmt.Errorf("第一层错误") //等于 errors.New("原始错误e") e = fmt.Errorf("第二层错误%w", e) e = fmt.Errorf("第三层错误%w", e) fmt.Println(e.Error()) // 第三层错误第二层错误第一层错误 fmt.Println(errors.Unwrap(e)) // 第二层错误第一层错误 fmt.Println(errors.Unwrap(errors.Unwrap(e))) //第一层错误 ``` ### Is 判断是否是同一个 error 判断是否是同一个 error,必须是同一个error 产生 ``` e := errors.New("123") e1 := e e2 := e fmt.Println(errors.Is(e1, e2)) //true e1 := errors.New("123") e2 := errors.New("123") fmt.Println(errors.Is(e1, e2))//false e := func() error { return errors.New("123") } e1 := e() e2 := e() fmt.Println(errors.Is(e1, e2)) //false ``` ### As 断言 从功能上来看,`As`所做的就是遍历err嵌套链,从里面找到类型符合的error ``` var perr *os.PathError if errors.As(err, &perr) { fmt.Println(perr.Path) } ``` ## 旧工程迁移 ### 直接返回 ``` return err // or return fmt.Errorf("more info: %v", err) //迁移 return fmt.Errorf("more info: %w", err) ``` ### == 判断 ``` if err == os.ErrExist //迁移 if errors.Is(err, os.ErrExist) ``` ### 断言 ``` if perr, ok := err.(*os.PathError); ok { fmt.Println(perr.Path) } //迁移 var perr *os.PathError if errors.As(err, &perr) { fmt.Println(perr.Path) } ``` ## 自定义error 结构体 不使用嵌套 ``` type MyError struct { When time.Time error string } // 使用 Error() 的接口都视为 error func (e MyError) Error() string { return fmt.Sprintf("%v: %v", e.When.Format(time.RFC3339), e.error) } func NewMyError(err string) error { return MyError{ time.Now(), err, } } func main() { err := NewMyError("this is test") fmt.Printf("%+v\n", err) // 2020-12-24T15:38:43+08:00: this is test } ``` 使用 嵌套 ``` type MyError struct { err error msg string } func (e *MyError) Error() string { return e.err.Error() + e.msg } //迁移 func (e *MyError) Unwrap() error { return e.err } ```