错误处理
目标
-
错误处理有哪些方式
-
错误处理隐藏的坑
-
错误处理最佳实践
错误处理的几种方式
errors.New()
通常用来创建一个新错误,错误判断是否相等可以直接用 ==
。
// 创建一个错误
var Err = errors.New("some error")
// 判断错误是否相等
if Err == f() {
fmt.Println("equal error")
}
fmt.Errorf()
错误可以层层包装,可以通过 errors.As()
来将错误转为某一个内层错误。也可以通过 errors.Is()
来判断错误是否存在于错误链中。
var err1 = errors.New("err1")
var err2 = fmt.Errorf("err2: %w", err1)
fmt.Println(errors.Is(err1, err2)) // true
// 用 as 转换错误
var perr *os.PathError
if errors.As(err, &perr) {
fmt.Println(perr.Path)
}
error implement
// implement error
type HTTPErr struct {
Code int
Msg string
}
func (he *HTTPErr) Error() string {
return fmt.Sprintf("code=%d, msg=%s ", he.Code, he.Msg)
}
func NewHTTPErr(code int, msg string) *HTTPErr {
return &HTTPErr{Code: code, Msg: msg}
}
// 实现了 error 接口后,HTTPErr 就可以当作 error 来使用
func f() error {
return NewHTTPErr(404, "not found")
}
var err = f()
var he *HTTPErr
if errors.As(err, he) {
fmt.Println(he.Code, he.Msg) // 404 not found
}
错误处理的坑
golang 在判断变量是否为 nil 时,实际上会判断两个部分:1. 类型 2. 值,当类型和值均为 nil 时才会判断为 nil。
func f() error {
return nil
}
err := f()
fmt.Println(err == nil) // true
func f2() error {
var e *HTTPErr
return e
}
err2 := f2()
// 可以理解为,空的 HTTPErr != 空的 error
fmt.Println(err2 == nil) // false