...
在 GoFrame 的工程目录中,有一个包 /internal/packedutility
,我们可以在此处编写我们自己的 err
处理,后面的代码可以做为参考,也可以直接复制过去用:
/internal/packedutility/err.go:
Code Block | ||
---|---|---|
| ||
type pErr struct { maps map[int]string } var Err = &pErr{ maps: map[int]string{ 0: "请求成功", 10001: "用户名或密码错误", 10002: "用户不存在", 99999: "未知错误", }, } // GetMsg 获取code码对应的msg func (c *pErr) GetMsg(code int) string { return c.maps[code] } // Skip 抛出一个业务级别的错误,不会打印错误堆栈信息 func (c *pErr) Skip(code int, msg ...string) (err error) { var msgStr string if len(msg) == 0 { msgStr = c.GetMsg(code) } else { msg = append([]string{c.GetMsg(code)}, msg...) msgStr = strings.Join(msg, ", ") } // NewWithOption 在低版本的 gf 上不存在,请改用 NewOption return gerror.NewWithOption(gerror.Option{ Stack: false, Text: msgStr, Code: gcode.New(code, "", nil), }) } // Sys 抛出一个系统级别的错误,使用特殊的code码:99999 // !!! 使用该方法时,它会打印错误堆栈信息到日志,但是一定不要把任何错误信息抛出到客户端,防止泄露系统信息 // !!! 推荐做法是在后置中间件中捕获 code 99999 的错误,然后返回给客户端一个统一的错误提示 func (c *pErr) Sys(err error) error { return gerror.NewCode(gcode.New(CodeErrSys, "", nil), err.Error()) } |
...
Code Block | ||
---|---|---|
| ||
type sMiddleware struct { } func init() { service.RegisterMiddleware(New()) } func New() *sMiddleware { return &sMiddleware{} } type Response struct { Code int `json:"code" dc:"业务码"` Message string `json:"message" dc:"业务码说明"` Data interface{} `json:"data" dc:"返回的数据"` } func (s *sMiddleware) Response(r *ghttp.Request) { r.Middleware.Next() if r.Response.BufferLength() > 0 { return } // 先过滤掉服务器内部错误 if r.Response.Status >= http.StatusInternalServerError { // 清除掉缓存区,防止服务器信息泄露到客户端 r.Response.ClearBuffer() r.Response.Writeln("服务器打盹了,请稍后再来找他!") } var ( res = r.GetHandlerResponse() err = r.GetError() code = gerror.Code(err) codeInt = code.Code() msg string ) if err != nil { // 如果是系统错误,不要把错误信息抛出到客户端,防止泄露系统信息 if codeInt == packedutility.CodeErrSys { msg = packedutility.Err.GetSysMsg() } else { msg = err.Error() } } else { code = gcode.CodeOK msg = packedutility.Err.GetMsg(code.Code()) } r.Response.WriteJson(Response{ Code: code.Code(), Message: msg, Data: res, }) } |
...
Code Block | ||
---|---|---|
| ||
s.Group("/", func(group *ghttp.RouterGroup) { group.Middleware(service.Middleware().Response) group.Bind( exception.NewV1(), ) }) |
结果
然后在服务文件中调用 packedutility/err
/internal/logic/exception/exception.go:
Code Block | ||
---|---|---|
| ||
func (s *sException) Business() error { return packedutility.Err.Skip(10001) } // System 这里我们对 gjson.Decode() 传入错误数据,用来模拟组件内部抛出err func (s *sException) System() error { _, err := gjson.Decode("") if err != nil { return packedutility.Err.Sys(err) } return nil } |
...