目录

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,“自定义错误信息”) 进行封装,然后再往上抛