Go Error处理

2019-01-21  本文已影响1人  Carrism

错误处理

}
~~~

Error

}
~~~

}
func (dbError *DBError) Error() string {
return "数据库错误"
}
~~~

当我们使用定义的DBError进行错误的返回之后便会打印“数据库错误”的信息。如果想让我们的错误在使用的时候更自由附带信息的话可以再自定义的结构体中定义字段,比如:

    type DBError struct {
        s string
    }
    func (dbError *DBError) Error() string {
        return dbError.s
    }

存在的问题

经过上面的自定义之后,我们可以让error附带我们想要的信息,但是对于开发者还是不够的,我们有可能需要知道出错的更多信息,哪个文件中的哪一行代码,这样更方便我们定位问题

解决

type stack []uintptr
type errorString struct {
    s string
    *stack
}
func callers() *stack {
    const depth = 32
    var pcs [depth]uintptr
    n := runtime.Callers(3, pcs[:])
    var st stack = pcs[0:n]
    return &st
}
func New(text string) error {
    return &errorString{
        s:   text,
        stack: callers(),
    }
}

以上源码是github.com/pkg/errors错误处理库的源码。它的使用很简单,如果我们要生成一个错误,可以使用New函数,自带调用堆栈信息

func New(message string) error

若有现成的error,我们需要对他进行再次包装处理,有三个函数可供选择

//只附加新的信息
func WithMessage(err error, message string) error

//只附加调用堆栈信息
func WithStack(err error) error

//同时附加堆栈和信息
func Wrap(err error, message string) error

上面的包装能够让我们找到错误的根本原因,本质上是库当中的Cause函数:

func Cause(err error) error {
    type causer interface {
        Cause() error
    }
//for循环一直找到最根本的错误
    for err != nil {
        cause, ok := err.(causer)
        if !ok {
            break
        }
        err = cause.Cause()
    }
    return err
}

格式化打印

%s,%v //功能一样,输出错误信息,不包含堆栈
%q //输出的错误信息带引号,不包含堆栈
%+v //输出错误信息和堆栈
上一篇下一篇

猜你喜欢

热点阅读