github.com/pkg/errors
这是Wrap(err error, msg string)
https://pkg.go.dev/github.com/pkg/errors#Wrap
这是WithMessage(err error, msg string)
https://pkg.go.dev/github.com/pkg/errors#WithMessage
这两个函数都实现了接口causer
https://pkg.go.dev/github.com/pkg/errors#Cause
这段代码适用于errors.WithMessage
,尽管我认为我应该使用errors.Wrap
forerrors.Cause
func main() {
err := errors.New("first")
err1 := errors.WithMessage(err, "tmp")
err2 := errors.WithMessage(err1, "tmp")
err3 := errors.WithMessage(err2, "tmp")
fmt.Printf("%s", errors.Cause(err3))
}
Run Code Online (Sandbox Code Playgroud)
Output: first
不同之处在于Wrap
包括调用堆栈。如果你点击 Go 文档中的某个函数名称,它就会带你到源代码,你可以看到这两个函数都非常短小简单,只有一处不同;whileWithMessage
使用给定的消息和原因(您传入的错误)创建一个新错误,并接受此错误并再次Wrap
包装它,如下所示:
&withStack{
err,
callers(),
}
Run Code Online (Sandbox Code Playgroud)
这err
是它刚刚创建的新错误(与您从 中得到的完全相同WithMessage
)并callers
填充调用堆栈。文档中指出了这一点(强调我的):
Wrap 返回一个错误,并在调用 Wrap 时用堆栈跟踪注释 err
中没有提到,WithMessage
因为它不是由该函数完成的。