- gerror
- 错误堆栈
fmt格式化Stack方法Cause方法- 日志输出支持
gerror
gerror模块提供了更丰富的错误处理功能。
使用方式:
import "github.com/gogf/gf/g/errors/gerror"
接口文档:
https://godoc.org/github.com/gogf/gf/g/errors/gerror
func New(value interface{}) errorfunc NewText(text string) errorfunc Cause(err error) errorfunc Stack(err error) stringfunc Wrap(err error, text string) errorfunc Wrapf(err error, format string, args ...interface{}) errortype Errorfunc (err *Error) Cause() errorfunc (err *Error) Error() stringfunc (err *Error) Format(s fmt.State, verb rune)func (err *Error) Stack() string
错误堆栈
标准库的error错误实现比较简单,无法进行堆栈追溯,对于产生错误时的上层调用者来讲不是很友好,无法获得错误的调用链详细信息。gerror支持错误堆栈记录,通过New*/Wrap*均会自动记录当前错误产生时的堆栈信息。
使用示例:
package mainimport ("fmt""github.com/gogf/gf/g/errors/gerror")func OpenFile() error {return gerror.New("permission denied")}func OpenConfig() error {return gerror.Wrap(OpenFile(), "configuration file opening failed")}func ReadConfig() error {return gerror.Wrap(OpenConfig(), "reading configuration failed")}func main() {fmt.Printf("%+v", ReadConfig())}
执行后,终端输出:
reading configuration failed: configuration file opening failed: permission denied1. reading configuration failed1). main.ReadConfig/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror2.go:182). main.main/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror2.go:252. configuration file opening failed1). main.OpenConfig/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror2.go:142). main.ReadConfig/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror2.go:183). main.main/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror2.go:253. permission denied1). main.OpenFile/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror2.go:102). main.OpenConfig/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror2.go:143). main.ReadConfig/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror2.go:184). main.main/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror2.go:25
可以看到,调用端可以通过Wrap方法将底层的错误信息进行层级叠加,并且包含完整的错误堆栈信息。
fmt格式化
通过以上示例我们可以看到,通过%+v的打印格式可以打印出完整的堆栈信息,当然gerror.Error对象支持多种fmt格式:
| 格式符 | 输出内容 |
|---|---|
%v, %s |
打印所有的层级错误信息,构成完成的字符串返回,多个层级使用:拼接。 |
%-v, %-s |
打印当前层级的错误信息,返回字符串。 |
%+s |
打印完整的堆栈信息列表。 |
%+v |
打印所有的层级错误信息字符串,以及完整的堆栈信息,等同于%s\n%+s。 |
使用示例:
package mainimport ("errors""fmt""github.com/gogf/gf/g/errors/gerror")func Error1() error {return errors.New("test1")}func Error2() error {return gerror.New("test2")}func main() {err1 := Error1()err2 := Error2()fmt.Printf("%s, %-s, %+s\n", err1, err1, err1)fmt.Printf("%v, %-v, %+v\n", err1, err1, err1)fmt.Printf("%s, %-s, %+s\n", err2, err2, err2)fmt.Printf("%v, %-v, %+v\n", err2, err2, err2)}
执行后,终端输出为:
test1, test1, test1test1, test1, test1test2, test2, 1. test21). main.Error2/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror1.go:152). main.main/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror1.go:20test2, test2, test21. test21). main.Error2/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror1.go:152). main.main/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror1.go:20
Stack方法
func Stack(err error) string
通过Stack方法我们可以获得error对象的完整堆栈信息,返回堆栈列表字符串。注意参数为标准库error类型,当该参数为gerror模块生成的error时,或者开发者自定义的error对象实现了gerror.ApiStack接口时支持打印,否则,返回空字符串。
使用示例:
package mainimport ("errors""fmt""github.com/gogf/gf/g/errors/gerror")func Error1() error {return errors.New("test1")}func Error2() error {return gerror.New("test2")}func main() {err1 := Error1()err2 := Error2()fmt.Println("err1:", gerror.Stack(err1))fmt.Println("err2:", gerror.Stack(err2))}
执行后,终端输出:
err1:err2:1. test21). main.Error2/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror3.go:152). main.main/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror3.go:20
Cause方法
func Cause(err error) error
通过Cause方法我们可以获得error对象的根错误信息(原始错误)。注意参数为标准库error类型,当该参数为gerror模块生成的error时,或者开发者自定义的error对象实现了gerror.ApiCause接口时支持打印,否则,返回输出的error对象。
使用示例:
package mainimport ("fmt""github.com/gogf/gf/g/errors/gerror")func OpenFile() error {return gerror.New("permission denied")}func OpenConfig() error {return gerror.Wrap(OpenFile(), "configuration file opening failed")}func ReadConfig() error {return gerror.Wrap(OpenConfig(), "reading configuration failed")}func main() {fmt.Println(gerror.Cause(ReadConfig()))}
执行后,终端输出:
permission denied
日志输出支持
glog日志管理模块天然支持对gerror错误堆栈打印支持,这种支持不是强耦合性的,而是通过fmt格式化打印接口支持的。
使用示例:
package mainimport ("errors""github.com/gogf/gf/g/os/glog""github.com/gogf/gf/g/errors/gerror")func Error1() error {return errors.New("test1")}func Error2() error {return gerror.New("test2")}func main() {glog.Println(Error1())glog.Println(Error2())}
执行后,终端输出:
2019-07-13 15:01:31.131 test12019-07-13 15:01:31.131 test21. test21). main.Error2/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror5.go:162). main.main/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/geg/errors/gerror/gerror5.go:21
