Golang编程模式:错误处理
包装错误
开发过程中一般我们推荐包装一下错误,而不是干巴巴地把err
给返回到上层,我们需要把一些执行的上下文加入。
通常来说,我们会使用 fmt.Errorf()
来完成这个事,比如:
if err != nil {
return fmt.Errorf("something failed: %v", err)
}
另外,在Go语言的开发者中,更为普遍的做法是将错误包装在另一个错误中,同时保留原始内容:
type authorizationError struct {
operation string
err error // original error
}
func (e *authorizationError) Error() string {
return fmt.Sprintf("authorization failed during %s: %v", e.operation, e.err)
}
当然,更好的方式是通过一种标准的访问方法,这样,我们最好使用一个接口,比如 causer
接口中实现 Cause()
方法来暴露原始错误,以供进一步检查:
type causer interface {
Cause() error
}
func (e *authorizationError) Cause() error {
return e.err
}
最佳实践
有个好消息:有一个第三方的错误库(github.com/pkg/errors)帮我们实现了以上功能,而且这个库,在各种 golang
项目中广泛使用,所以这个基本上来说就是事实上的标准了。
列举几个常见的项目:
信息来源:https://deps.dev/go/github.com%2Fpkg%2Ferrors/v0.9.1/dependents,有兴趣的同学可以访问查看
代码示例如下:
import "github.com/pkg/errors"
//错误包装
if err != nil {
return errors.Wrap(err, "read failed")
}
// Cause接口
switch err := errors.Cause(err).(type) {
case *MyError:
// handle specifically
default:
// unknown error
}
参考文章
https://coolshell.cn/articles/21140.html
Last updated