Go-error

PackageerrorsGo语言提供了错误处理的函数。

error的定义:

1
2
3
type error interface {
Error() string
}

errors中提供的方法

1
2
3
4
5
6
7
8
9
10
11
// 根据给定的字符串返回一个error类型
func New(text string) error

// 在错误链中查找第一个等于target的错误,并将target设置为这个错误返回true,否则返回false
func As(err error, target interface{}) bool

// 判断错误链中是否包含target类型的错误
func Is(err, target error) bool

//调用参数err本身的Unwrap方法,如果err存在Unwrap方法返回该方法返回的值,否则返回nil
func Unwrap(err error) error

Go1.13开始提供了Unwarp方法来获取嵌套的错误。
1.创建一个嵌套的错误
方法一:通过fmt.Error("%w", err)来创建

1
2
3
4
5
6
7
8
9
func main() {
err1 := errors.New("new err")
err2 := fmt.Errorf("err2: [%w]", err1)
// err2: [new err]
fmt.Println(err2)
e := errors.Unwrap(err2)
// new err
fmt.Println(e)
}

方法二:自定义结构体,并实现Error()Unwrap()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
type QueryError struct {
Query string
Err error
}

func (e *QueryError) Error() string {
return e.Query
}

func (e *QueryError) Unwrap() error {
return e.Err
}


func main() {
err1 := QueryError{"select", errors.New("permission denied")}
e := errors.Unwrap(&err1)

// output: permission denied
fmt.Println(e)
}

2.errors.Is判断嵌套的error是否包含特定的错误

1
2
3
4
5
6
func main() {
err1 := errors.New("new err")
err2 := fmt.Errorf("err2: [%w]", err1)
// output: true
fmt.Println(errors.Is(err2, err1))
}

3.errors.As判断错误链中是否包含target类型的错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type QueryError struct {
Query string
}

func (e *QueryError) Error() string {
return e.Query
}


func main() {
var target *QueryError
err2 := fmt.Errorf("err2: [%w]", &QueryError{Query:"select error"})
// output: true
fmt.Println(errors.As(err2, &target))

}


REF:
1.https://blog.golang.org/go1.13-errors
2.https://golang.org/pkg/errors/