errors
最后更新于:2022-04-02 02:43:39
[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
}
```
';