go 使用 pkg error 包打印错误堆栈信息
背景
在使用 go 标准库 errors 包封装 err 错误信息,控制台打印时只有错误信息,没有实际堆栈
package main
import (
"errors"
"fmt"
)
func main() {
err := NewErr("this is err msg")
fmt.Printf("%v\n", err)
}
this is err msg
那么如何才能实现打印数据,同时输出 trace 调用栈信息呢?使用 github.com/pkg/errors 替换 errors 包
pkg errors
使用 github.com/pkg/errors 替换 errors 包,可以无缝替换,因为 pkg/errors 包的 api 和 errors 几乎一致,但是功能更加强大
打印错误堆栈:
替换导包,并且使用 %+v 占位符,否则无法打印堆栈
package main
import (
"github.com/pkg/errors"
"fmt"
)
func main() {
err := NewErr("this is err msg")
fmt.Printf("%+v\n", err)
}
func NewErr(s string) error {
return errors.New(s)
}
this is err msg main.NewErr xxxx/main.go:43 main.main xxxx/main.go:38 runtime.main xxxx/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.4.darwin-arm64/src/runtime/proc.go:272 runtime.goexit xxxx/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.4.darwin-arm64/src/runtime/asm_arm64.s:1223
也可以对已存在的 err 进行包装,包含堆栈信息
func main() {
err := NewNoTraceErr("this is err msg")
err = errors.WithStack(err)
fmt.Printf("%+v\n", err)
}
func NewNoTraceErr(s string) error {
return fmt.Errorf("err:%s", s)
}
err:this is err msg main.main xxx/go/src/it******.com/learn-go/main.go:39 runtime.main …
此时你会发现堆栈的信息只能追踪到:err = errors.WithStack(err)
所以:堆栈只能追踪到:只有在使用了 pkg/errors 包封装的代码位置
第三方库的代码绝大多数都没有使用 github.com/pkg/errors
。
⚠️⚠️:
所以在使用第三方库的时,err 应该用 errors.WithStack(err) 或者 errors.Wrap(err,“自定义错误信息”) 进行封装,然后再往上抛