## 使用第三方errors包 位于[github.com/pkg/errors](github.com/pkg/errors) 的errors包是Go标准库的替代品。它提供了一些非常有用的操作用于封装和处理错误。在之前的章节我们已经看到了如何对错误进行封装,值得注意的是,使用标准库的方式对错误进行封装,会改变其类型并使类型断言失败。 本节我们会演示对[github.com/pkg/errors](github.com/pkg/errors) 的使用。 ### 实践 1. 获取第三方库: ``` go get github.com/pkg/errors/ ``` 2. 建立errwrap.go : ``` package errwrap import ( "fmt" "github.com/pkg/errors" ) // WrappedError 演示了如何对错误进行封装 func WrappedError(e error) error { return errors.Wrap(e, "An error occurred in WrappedError") } type ErrorTyped struct { error } func Wrap() { e := errors.New("standard error") fmt.Println("Regular Error - ", WrappedError(e)) fmt.Println("Typed Error - ", WrappedError(ErrorTyped{errors.New("typed error")})) fmt.Println("Nil -", WrappedError(nil)) } ``` 2. 建立unwrap.go : ``` package errwrap import ( "fmt" "github.com/pkg/errors" ) // Unwrap 解除封装并进行断言处理 func Unwrap() { err := error(ErrorTyped{errors.New("an error occurred")}) err = errors.Wrap(err, "wrapped") fmt.Println("wrapped error: ", err) // 处理错误类型 switch errors.Cause(err).(type) { case ErrorTyped: fmt.Println("a typed error occurred: ", err) default: fmt.Println("an unknown error occurred") } } // StackTrace 打印错误栈 func StackTrace() { err := error(ErrorTyped{errors.New("an error occurred")}) err = errors.Wrap(err, "wrapped") fmt.Printf("%+v\n", err) } ``` 2. 建立main.go : ``` package main import ( "fmt" "github.com/agtorre/go-cookbook/chapter4/errwrap" ) func main() { errwrap.Wrap() fmt.Println() errwrap.Unwrap() fmt.Println() errwrap.StackTrace() } ``` 2. 这会输出 : ``` Regular Error - An error occurred in WrappedError: standard error Typed Error - An error occurred in WrappedError: typed error Nil - <nil> wrapped error: wrapped: an error occurred a typed error occurred: wrapped: an error occurred an error occurred github.com/agtorre/go-cookbook/chapter4/errwrap.StackTrace /Users/lothamer/go/src/github.com/agtorre/gocookbook/chapter4/errwrap/unwrap.go:30 main.main /tmp/go/src/github.com/agtorre/gocookbook/chapter4/errwrap/example/main.go:14 ``` ### 说明 封装错误在开发中很常见,尤其对日志及问题查找作用巨大。该示例为大家提供了基本的思路。此外,该库对错误为nil的情况进行了处理: ``` func RetError() error{ err := ThisReturnsAnError() return errors.Wrap(err, "This only does something if err != nil") } ``` 该库的作者Dave Cheney提供了一系列的博客来讨论Go语言的错误处理,可以查看[https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully](https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully)以了解更多。 * * * * 学识浅薄,错误在所难免。欢迎在群中就本书提出修改意见,以飨后来者,长风拜谢。 Golang中国(211938256) beego实战(258969317) Go实践(386056972)