问题描述:
beego默认的异常返回信息是一个网页,不利于bug排查、前端适配和美观度等问题
问题分析:
执行过程遇到异常,最终都会通过RecoverFunc执行
(beego/router.go 710)
默认的recover函数是:recoverPanic
(beego/config.go 710)
默认处理逻辑如下,返回一个前端页面用于报错的逻辑见198行showErr函数
(beego/config.go 172)
解决办法:
1. 仅仅只是不想显示前端页面:
在配置文件app.conf中添加配置:EnableErrorsRender = false 或 RunMode = prod
2. 如果需要返回相应的json信息:
需要重写recoverPanic方法,并在main函数中注册
package main
import (
beego "github.com/astaxie/beego"
common "myproject/common"
_ "myproject/routers"
)
func main() {
//这里将自定义错误处理注册进去
beego.BConfig.RecoverFunc = common.RecoverPanic
beego.Run()
}
package common
import (
"fmt"
"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/logs"
"runtime"
)
func RecoverPanic(ctx *context.Context) {
if err := recover(); err != nil {
if err == beego.ErrAbort {
return
}
// 是否执行RecoverPanic后续逻辑还是直接抛出异常
if !beego.BConfig.RecoverPanic {
panic(err)
}
// EnableErrorsShow用于配置是否处理错误
if beego.BConfig.EnableErrorsShow {
if _, ok := beego.ErrorMaps[fmt.Sprint(err)]; ok {
// beego自带的对于特定错误的处理逻辑,比如401显示没有授权的页面
//exception(fmt.Sprint(err), ctx)
return
}
}
//自定义错误打印 stack堆栈信息
var stack string
logs.Critical("the request url is ", ctx.Input.URL())
logs.Critical("Handler crashed with error", err)
for i := 1; ; i++ {
_, file, line, ok := runtime.Caller(i)
if !ok {break}
logs.Critical(fmt.Sprintf("%s:%d", file, line))
stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line))
}
// 设置响应头为 JSON 格式
ctx.ResponseWriter.Header().Set("Content-Type", "application/json")
// 设置自定义的状态码
if ctx.Output.Status != 0 {
ctx.ResponseWriter.WriteHeader(ctx.Output.Status)
} else {
ctx.ResponseWriter.WriteHeader(500)
}
//自定义返回信息
data := map[string]interface{}{
"ret": 4000,
"AppError": fmt.Sprintf("%v", err),
"RequestMethod": ctx.Input.Method(),
"RequestURL": ctx.Input.URI(),
"RemoteAddr": ctx.Input.IP(),
"Stack": stack,
"BeegoVersion": beego.VERSION,
"GoVersion": runtime.Version(),
}
_ = ctx.Output.JSON(data, true, true)
}
}
结果展示:
配置 EnableErrorsRender = false 或 RunMode = prod:
重写recoverPanic方法: