go中如何处理错误error实践 | 青训营

58 阅读3分钟

一.go中错误的处理

对于Go语言(golang)的错误设计,相信很多人已经体验过了,它是通过返回值的方式,来强迫调用者对错误进行处理,要么你忽略,要么你处理(处理也可以是继续返回给调用者),对于golang这种设计方式,我们会在代码中写大量的if判断,以便做出决定。

func main() {
    conent,err:=ioutil.ReadFile("filepath")
    if err !=nil{
        //错误处理
    }else {
        fmt.Println(string(conent))
    }
}

对于一个从java过来的开发者来说,十分难受。不过我们可以通过error接口,来实现自定义的error

二.实现error接口

error其实一个接口,内置的,我们看下它的定义

type error interface {
    Error() string
}

它只有一个方法 Error,只要实现了这个方法,就是实现了error。现在我们自己定义一个错误试试。

type fileError struct {
}

func (fe *fileError) Error() string {
    return "文件错误"
}

进行测试

func main() {
    conent, err := openFile()
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(string(conent))
    }
}

//只是模拟一个错误
func openFile() ([]byte, error) {
    return nil, &fileError{}
}

我们运行模拟的代码,可以看到文件错误的通知。

在实际的使用过程中,我们可能遇到很多错误,他们的区别是错误信息不一样,一种做法是每种错误都类似上面一样定义一个错误类型,但是这样太麻烦了。我们发现Error返回的其实是个字符串,我们可以修改下,让这个字符串可以设置就可以了。

type fileError struct {
    s string
}

func (fe *fileError) Error() string {
    return fe.s
}

我们可以将它变的更通用一些,比如修改fileError的名字,再创建一个辅助函数,便于我们创建不同的错误类型。

func New(text string) error {
    return &errorString{text}
}

type errorString struct {
    s string
}

func (e *errorString) Error() string {
    return e.s
}

变成以上这样,我们就可以通过New函数,辅助我们创建不同的错误了,这其实就是我们经常用到的errors.New函数,被我们一步步剖析演化而来,现在大家对Go语言(golang)内置的错误error有了一个清晰的认知了。

三.使用错误库

虽然Go语言对错误的设计非常简洁,但是对于我们开发者来说,很明显是不足的,比如我们需要知道出错的更多信息,在什么文件的,哪一行代码?只有这样我们才更容易的定位问题。 还有比如,我们想对返回的error附加更多的信息后再返回,比如以上的例子,我们怎么做呢?我们只能先通过Error方法,取出原来的错误信息,然后自己再拼接,再使用errors.New函数生成新错误返回。 因为Go语言提供的错误太简单了,以至于简单的我们无法更好的处理问题,甚至不能为我们处理错误,提供更有用的信息,所以诞生了很多对错误处理的库,github.com/pkg/errors是比较简洁的一样,并且功能非常强大,受到了大量开发者的欢迎,使用者很多。

func New(message string) error

它的使用非常简单,如果我们要新生成一个错误,可以使用New函数,生成的错误,自带调用堆栈信息。 如果有一个现成的error,我们需要对他进行再次包装处理,这时候有三个函数可以选择。

func WithMessage(err error, message string) error

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

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

这个错误库里面有许多有用的方法,有需要可以go get一下。

四.总结

通过使用这个 github.com/pkg/errors 错误库,我们可以收集更多的信息,可以让我们更容易的定位问题。我们收集的这些信息不止可以输出到控制台,也可以当做日志,使用输出到相应的Log日志里,便于分析问题。