我想用堆栈跟踪注解错误,因此我使用/pkg/errors包。
Go 1.13添加了%w -格式化动词来Wrap errors。
下面的程序不使用%w打印一个很好的堆栈跟踪:
https://play.golang.org/p/eAwMrwqjCWX
以下仅使用%w not稍微修改的程序:
https://play.golang.org/p/am34kdC0E3o
我应该如何将%w与错误 Package 和堆栈跟踪一起使用?
我想用堆栈跟踪注解错误,因此我使用/pkg/errors包。
Go 1.13添加了%w -格式化动词来Wrap errors。
下面的程序不使用%w打印一个很好的堆栈跟踪:
https://play.golang.org/p/eAwMrwqjCWX
以下仅使用%w not稍微修改的程序:
https://play.golang.org/p/am34kdC0E3o
我应该如何将%w与错误 Package 和堆栈跟踪一起使用?
2条答案
按热度按时间b1payxdu1#
原因是
errors.Errorf
删除了新的fundamental
错误类型(在pkg/errors
中)。如果你看看它的方法Format(s fmt.State, verb rune)
(当你执行log.Printf
时触发):所以你可以看到它只打印
io.WriteString(s, f.msg)
。Errorf
是:因为这条线:
fmt.Sprintf(format, args...)
你会看到go vet的错误(你不能把%w
传递给Sprintf
),在错误消息的打印中你会看到:而当使用
Wrap
方法时,您将获得withStack
错误类型,其Format
方法为:由于这行
fmt.Fprintf(s, "%+v", w.Cause())
,您可以看到一个很好的递归堆栈跟踪。基本上,你需要像这样使用
%w
:但如果你想打印堆栈,这不会有帮助。
你可以做的是自己实现一个递归打印堆栈跟踪的函数,它将在
fmt
或pkg/errors
的错误链上工作:https://play.golang.org/p/OsEPD6guWtO
gmol16392#
github.com/pkg/errors
已被弃用,并且不会获得更新的Go(错误处理)功能。不久前,我将its spiritual successor命名为gitlab.com/tozd/go/errors
,它解决了github.com/pkg/errors
的一长串问题。其中之一,errors.Errorf
只适用于%w
。您可以使用gitlab.com/tozd/go/errors
作为github.com/pkg/errors
的直接替代品,然后您的示例程序看起来像:输出量:
请注意,堆栈跟踪正确地从
myerror
开始(也就是原始错误发生的地方),而不是从main
开始(您调用Errorf
的地方)。Errorf
正确地检测到原始错误已经有堆栈跟踪,并且不会添加另一个堆栈跟踪或覆盖它。