Go 学习笔记(72)— Go 第三方库之 errors 带堆栈的错误处理

github.com/pkg/errors 让开发人员很容易在 error 错误信息上带上堆栈信息,可以更快更准确定位错误,例如行号等信息。

如果项目代码比较复杂,且经常需要追踪 Bug,建议使用 github.com/pkg/errors 这个错误处理包。

安装

go get -v github.com/pkg/errors

这个包和标准库的 errors 包重名,并且都有 New() 函数,因此从标准库的错误处理方式转为带堆栈的错误处理上来还是比较方便的。下面代码使用 errors.Wrap() 函数对错误信息进行了包装:

package main

import (
    "fmt"

    "github.com/pkg/errors"
)

var ErrNameEmpty = errors.New("Name can't be empty!")

func (s *Student) SetName(newName string) (err error) {
    
    
    if newName == "" || s.Name == "" {
    
    
        return ErrNameEmpty
    } else {
    
    
        s.Name = newName
        return nil
    }
}

type Student struct {
    
    
    Name string
    Age  int
}

func NewStu() (err error) {
    
    
    stu := &Student{
    
    Age: 19}
    e := stu.SetName("")

    if e != nil {
    
    
        return errors.Wrap(e, "set name failed!")
    } else {
    
    
        return nil
    }

}

func main() {
    
    
    e := NewStu()
    fmt.Printf("%+v\n", e)
}

最后通过 Printf() ,设置占位符 %+v 显示错误信息和堆栈信息,例如函数运行时的文件名、行数等信息,而占位符 %s 则只显示错误信息。

下面带堆栈信息的错误提示很容易让程序员定位问题发生的位置,比如 main.go:30 ,表明在 main.go 文件的 30 行。

Name can't be empty!
main.init
    main.go:9
runtime.main
    /src/runtime/proc.go:189
runtime.goexit
    /src/runtime/asm_amd64.s:1333
set name failed!
main.NewStu
    main.go:30
main.main
    main.go:38
runtime.main
    /src/runtime/proc.go:201
runtime.goexit
    /src/runtime/asm_amd64.s:1333
  • Wrap() 函数在已有错误基础上同时附加堆栈信息和新提示信息,
  • WithMessage() 函数在已有错误基础上附加新提示信息,
  • WithStack() 函数在已有错误基础上附加堆栈信息。在实际中可根据情况选择使用。

这个包比较简洁实用,而且有可能会纳入标准库,所以建议在实际生产中使用。
另外环境变量 GOTRACEBACK 对堆栈信息的输出信息量有较大影响,不同的值有不同详细程度的信息输出。

  • GOTRACEBACK = none
  • GOTRACEBACK = single(默认值)
  • GOTRACEBACK = all
  • GOTRACEBACK = system
  • GOTRACEBACK = crash

在程序中 debug.SetTraceback (level string) 函数也可以设置该变量。

猜你喜欢

转载自blog.csdn.net/wohu1104/article/details/113795455
今日推荐