package http_middleware import ( "fmt" "git.aionnect.com/aionnect/go-common/utils" "git.aionnect.com/aionnect/go-common/utils/date" "git.aionnect.com/aionnect/go-common/utils/logger" "github.com/gin-gonic/gin" "net/http" "strings" ) // Recovery中间件(统一错误处理) func Recovery(hostPrefix string, logger *logger.Logger) gin.HandlerFunc { return func(ctxt *gin.Context) { defer func() { if err := recover(); err != nil && logger != nil { stack := string(utils.GetStack(4)) if i, ok := ctxt.Get(HTTPRequestStartTime); ok { if start, ok := i.(date.Datetime); ok { end := date.Now() latency := end.Sub(start) logger = logger.WithField("latency", fmt.Sprintf("%v", latency)) } } clientIP := ctxt.ClientIP() comment := ctxt.Errors.ByType(gin.ErrorTypePrivate).String() req, fields := splitUri(hostPrefix, ctxt) logHttpRequest := true if i, ok := ctxt.Get(IsNoLogHTTPRequest); ok { if isNoLogHttpRequest, ok := i.(bool); ok && isNoLogHttpRequest { logHttpRequest = false } } if logHttpRequest { if reader, ok := ctxt.Request.Body.(*reqBodyLogReader); ok { logger = logger.WithField("requestBody", reader.buffer.String()) } } logger = logger. WithField("clientIP", clientIP). WithField("comment", comment). WithFields(fields) var res *utils.Res if r, ok := err.(*utils.Res); ok { res = r } else if r, ok := err.(utils.Res); ok { res = &r } if res != nil { httpStatus := http.StatusBadRequest var s1, s2 string if nil != &res.Head { if res.Head.HttpStatus > 0 { httpStatus = res.Head.HttpStatus } s1 = res.Head.ErrMsg s2 = res.Head.Detail if strings.Contains(s2, s1) { s1 = "" } if strings.Contains(s1, s2) { s2 = "" } } else { res.Head = utils.ResHead{ErrCode: -1, ErrMsg: "未定义"} } if i, ok := ctxt.Get(IsLogHTTPResponse); ok { if isLogHttpResponse, ok := i.(bool); ok && isLogHttpResponse { respData, _ := res.MarshalJSON() logger = logger.WithField("responseBody", string(respData)) } } logger. WithCaller(4). WithField("tag", "Custom warn"). WithField("httpStatus", httpStatus). WithField("errCode", res.Head.ErrCode). WithField("errMsg", strings.TrimSpace(fmt.Sprintf("%d %s %s", res.Head.ErrCode, s1, s2))). Warn(req) ctxt.JSON(httpStatus, res) ctxt.Abort() } else { res := utils.E(9999, "未定义", nil) if i, ok := ctxt.Get(IsLogHTTPResponse); ok { if isLogHttpResponse, ok := i.(bool); ok && isLogHttpResponse { logger = logger.WithField("responseBody", `{"head":{"errcode":9999,"errmsg":"未定义"}}`) } } logger. WithCaller(5). WithField("tag", "Catch Exception"). WithField("httpStatus", http.StatusBadRequest). WithField("errCode", 9999). WithField("errMsg", fmt.Sprintf("9999 %s", err)). Error(req) println(stack) ctxt.JSON(http.StatusBadRequest, res) ctxt.Abort() } } }() ctxt.Next() } }