What difference between errors.Wrap and errors.WithMessage

huangapple go评论83阅读模式
英文:

What difference between errors.Wrap and errors.WithMessage

问题

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 来获取 errors.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))
}

输出结果为:first

英文:

github.com/pkg/errors

This is Wrap(err error, msg string) https://pkg.go.dev/github.com/pkg/errors#Wrap

This is WithMessage(err error, msg string) https://pkg.go.dev/github.com/pkg/errors#WithMessage

both of these functions implement the interface causer https://pkg.go.dev/github.com/pkg/errors#Cause

This code works with errors.WithMessage, although I thought I should use errors.Wrap for errors.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))
}

Output: first

答案1

得分: 5

WrapWithMessage的区别在于Wrap包含了调用堆栈。如果你在Go文档中点击函数名,它会带你到源代码,你可以看到这两个函数非常简短和简单,只有一个区别;WithMessage创建一个带有给定消息和原因(传入的错误)的新错误,而Wrap则将此错误再次包装,如下所示:

&withStack{
	err,
	callers(),
}

这里,err是刚刚创建的新错误(与WithMessage得到的错误完全相同),而callers填充了一个调用堆栈。这在文档中有说明(我加了重点):

> Wrap在调用时返回一个带有堆栈跟踪的注释错误

WithMessage中没有提到这一点,因为该函数不执行这个操作。

英文:

The difference is that Wrap includes a call stack. If you click on a function name in the Go documentation, it will take you to the source, and you can see that both these functions are quite short and simple, and there is only one difference; while WithMessage creates a new error with the given message and cause (the error you pass in), Wrap takes this error and wraps it again like so:

&withStack{
	err,
	callers(),
}

Here err is the new error it just created (exactly like what you'd get from WithMessage) and callers populates a call stack. This is indicated in the documentation (emphasis mine):

> Wrap returns an error annotating err with a stack trace at the point Wrap is called

Which is not mentioned in WithMessage as it's not done by that function.

huangapple
  • 本文由 发表于 2023年1月20日 05:38:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75178554.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定