Go errors 默认加堆栈信息,有用不?
大家好,我是煎鱼。
在 Go 语言中,错误处理是我们必须涉及和争议比较大的一个功能特性。今天我们不太探讨 if err != nil 的繁杂忧愁。(因为探讨过好多次了)
本文聚焦在 errors 标准库在排查、定位问题的诉求上。看看大家平时都是怎么做的。
背景
平时我们在返回和处理错误时,一般使用 errors 标准库。其支持以下几个 API:
func As(err error, target any) bool
func Is(err, target error) bool
func Join(errs ...error) error
func New(text string) error
func Unwrap(err error) error
最简单的 Demo 如下:
func main() {
err := errors.New("煎鱼出现错误了!")
if err != nil {
fmt.Println(err)
}
}
输出结果:
煎鱼出现错误了!
看着非常基础,也没什么特别的。但如果是在生产等正式环境下出问题时,可能就没法这么愉快了。
但比较头疼的是:其错误信息缺乏了调用堆栈,在复杂程序下,你很难直观的知道是具体哪些关联的代码导致出现了这个报错。只能靠在代码中搜错误的文本,去猜测应该是这里的问题。
第三方库解决
因此很多同学会使用第三方的开源库 go-errors/errors
。以下是他的简单代码演示:
import (
"fmt"
"github.com/go-errors/errors"
)
var Crashed = errors.Errorf("煎鱼变炸鱼了!")
func Crash() error {
return errors.New(Crashed)
}
func main() {
err := Crash()
if err != nil {
fmt.Println(err.(*errors.Error).ErrorStack())
return
}
}
输出结果:
$ go run main.go
*errors.Error 煎鱼变炸鱼了!
/Users/eddycjy/app/go/demo1/main.go:12 (0x1090645)
main: return errors.New(Crashed)
/Users/eddycjy/app/go/demo1/main.go:12 (0x1090636)
Crash: return errors.New(Crashed)
/usr/local/Cellar/go/1.21.1/libexec/src/runtime/internal/atomic/types.go:194 (0x103305b)
(*Uint32).Load: return Load(&u.value)
/usr/local/Cellar/go/1.21.1/libexec/src/runtime/asm_amd64.s:1650 (0x105d501)
goexit: BYTE $0x90 // NOP
该库会默认记录 ErrorStack 并且可以通过相应的方法获得。
新提案
前面提到的问题和解决方案,一直有人在提和重复造新的轮子。最近 Go 核心团队 @Ian Lance Taylor 提出了新的提案《proposal: errors: let GODEBUG=errstacktrace request stack backtraces[1]》希望以此解决这个问题。
在提案中计划:增加一个新的 Go 运行时选项:GODEBUG=errstacktrace
。
在环境中设置该 GODEBUG 项后,errors.New
和 fmt.Errorf
函数将发生变化,将堆栈跟踪纳入存储的信息中。
新补充的堆栈跟踪将成为 Error 方法返回的字符串的一部分,将会是一个多行的字符串内容。
当前该提案正在征集更多的建议,目测挺有戏,欢迎大家点赞转发表达想法!
总结
Go 的 errors 总是纷纷扰扰,本次的提案也是拉扯了多年的结果。本次是想往 GODEBUG 上做开关选项,但也有许多同学想在编译时就能指定,不用每次配一堆 GODEBUG。(虽然实际效果差不多)
整体来讲,这个需求如果能够落地,还是不错的。能够解决一些缺失调用堆栈,不太能明确错误抛出在哪的小麻烦。也能解决一些第三方库存在原因,不用再额外维护了。
推荐阅读
参考资料
proposal: errors: let GODEBUG=errstacktrace request stack backtraces: https://github.com/golang/go/issues/63358
关注和加煎鱼微信,
一手消息和知识,拉你进技术交流群👇
你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路。
日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!