GoFrame错误处理
背景
Go服务接口报错,接口返回只有一行错误信息,没有具体的堆栈信息和告警,不方便排除错误
Go Error
Go 中的每一个错误都需要处理。错误应该明确地当成业务的一部分,任何可以预见的问题都需要做错误处理。
Go 语言中,Go Error 是一个接口。实现、创建或抛出错误,实际上就是实现这个接口。
http://golang.org/pkg/builtin/#error
// The error built-in interface type is the conventional interface for// representing an error condition, with the nil value representing no error.type error interface {Error() string}
Go Error 缺少上下文信息,一般会使用第三方的错误库(github.com/pkg/errors),把一些执行的上下文加入,将错误包装在另一个错误中,同时保留原始内容。使用 New 函数生成的错误,自带调用堆栈信息。
// 新生成一个错误, 带堆栈信息func New(message string) error// 只附加新的信息func WithMessage(err error, message string) error// 只附加调用堆栈信息func WithStack(err error) error// 同时附加堆栈和信息func Wrapf(err error, format string, args ...interface{}) error// 获得最根本的错误原因func Cause(err error) error例子:_, err := ioutil.ReadAll(r)if err != nil {return errors.Wrap(err, "read failed")}
GoFrame的错误处理
错误处理组件
全错误堆栈设计
web服务异常处理
在业务处理返回错误信息,使用gerror错误组件返回错误信息
gerror.New("错误信息")
使用内置错误码返回
https://github.com/gogf/gf/blob/master/errors/gcode/gcode.go
gerror.NewCode(gcode.CodeInternalError, "错误信息")
使用指定错误码返回
gerror.NewCode(gcode.New(10000, "", nil), "错误信息")
异常错误中间件
GoFrame HTTP执行流程中产生panic异常时,默认处理是记录到Serve的日志文件中。支持通过注册中间件方式手动捕获,然后自定义相关的错误处理。
GoFrame在中间件提供r.GetError()的方法获取错误的信息,支持通过%+v打印详细的堆栈信息。
func HandlerError(r *ghttp.Request) {r.Middleware.Next()if err := r.GetError(); err != nil {wlog.New().Errorf(r.GetCtx(), "%+v", err)}}
把错误处理的中间件引入使用,可以实现框架的统一错误处理
apiServer.Group("/", func(group *ghttp.RouterGroup) {group.Middleware(w.Middleware(ctx).HandlerError,ghttp.MiddlewareHandlerResponse,)router.BindController(group)})
1、日志打印错误和堆栈信息
2、Error级别日志触发告警通知