背景
go 遵循 errors are values 的理念,内置 error 提供的信息比较有限,如:
_, err := os.Open("a.txt") // open a.txt: no such file or directory
然而 error 出现在哪行?调用堆栈是怎样的?不得而知。在实际使用时,这些信息的缺失不利用 Troubleshooting。这也是本文要探究的 go 错误处理的最佳实践
解决方案
pkg/errors 的作者 Dave Cheney 经过大量的思考,赋予了 error context 的能力,很好的解决了上述提到的问题
pkg/errors
分析
pkg/errors
主要有两类 func
一类是 Wrap
,赋予 error context 的能力
// Wrap annotates cause with a message.
func Wrap(cause error, message string) error
另一类是 Cause
,获取 error chain 源头处 error
// Cause unwraps an annotated error.
func Cause(err error) error
pkg/errors
有三个实现 error 接口的 struct,分别是 fundamental
/withStack
/withMessage
fundamental
通过 errors.New(msg)
创建,用于初始化 error, 作为 error chain 的源头
withMessage
通过 errors.WithMessage(err, msg)
创建,用于 wrapper 已有 error 并添加 msg
withStack
通过 errors.WithStack(err)
创建,用于 wrapper 已有 error 并添加 trace,若还需额外 msg 可使用 errors.Wrap(err, msg)
fmt.Printf("%+v", err)
用来打印 stack trace