gin_recovery.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package http_middleware
  2. import (
  3. "fmt"
  4. "git.aionnect.com/aionnect/go-common/utils"
  5. "git.aionnect.com/aionnect/go-common/utils/date"
  6. "git.aionnect.com/aionnect/go-common/utils/logger"
  7. "github.com/gin-gonic/gin"
  8. "net/http"
  9. "strings"
  10. )
  11. // Recovery中间件(统一错误处理)
  12. func Recovery(hostPrefix string, logger *logger.Logger) gin.HandlerFunc {
  13. return func(ctxt *gin.Context) {
  14. defer func() {
  15. if err := recover(); err != nil && logger != nil {
  16. stack := string(utils.GetStack(4))
  17. if i, ok := ctxt.Get(HTTPRequestStartTime); ok {
  18. if start, ok := i.(date.Datetime); ok {
  19. end := date.Now()
  20. latency := end.Sub(start)
  21. logger = logger.WithField("latency", fmt.Sprintf("%v", latency))
  22. }
  23. }
  24. clientIP := ctxt.ClientIP()
  25. comment := ctxt.Errors.ByType(gin.ErrorTypePrivate).String()
  26. req, fields := splitUri(hostPrefix, ctxt)
  27. logHttpRequest := true
  28. if i, ok := ctxt.Get(IsNoLogHTTPRequest); ok {
  29. if isNoLogHttpRequest, ok := i.(bool); ok && isNoLogHttpRequest {
  30. logHttpRequest = false
  31. }
  32. }
  33. if logHttpRequest {
  34. if reader, ok := ctxt.Request.Body.(*reqBodyLogReader); ok {
  35. logger = logger.WithField("requestBody", reader.buffer.String())
  36. }
  37. }
  38. logger = logger.
  39. WithField("clientIP", clientIP).
  40. WithField("comment", comment).
  41. WithFields(fields)
  42. var res *utils.Res
  43. if r, ok := err.(*utils.Res); ok {
  44. res = r
  45. } else if r, ok := err.(utils.Res); ok {
  46. res = &r
  47. }
  48. if res != nil {
  49. httpStatus := http.StatusBadRequest
  50. var s1, s2 string
  51. if nil != &res.Head {
  52. if res.Head.HttpStatus > 0 {
  53. httpStatus = res.Head.HttpStatus
  54. }
  55. s1 = res.Head.ErrMsg
  56. s2 = res.Head.Detail
  57. if strings.Contains(s2, s1) {
  58. s1 = ""
  59. }
  60. if strings.Contains(s1, s2) {
  61. s2 = ""
  62. }
  63. } else {
  64. res.Head = utils.ResHead{ErrCode: -1, ErrMsg: "未定义"}
  65. }
  66. if i, ok := ctxt.Get(IsLogHTTPResponse); ok {
  67. if isLogHttpResponse, ok := i.(bool); ok && isLogHttpResponse {
  68. respData, _ := res.MarshalJSON()
  69. logger = logger.WithField("responseBody", string(respData))
  70. }
  71. }
  72. logger.
  73. WithCaller(4).
  74. WithField("tag", "Custom warn").
  75. WithField("httpStatus", httpStatus).
  76. WithField("errCode", res.Head.ErrCode).
  77. WithField("errMsg", strings.TrimSpace(fmt.Sprintf("%d %s %s", res.Head.ErrCode, s1, s2))).
  78. Warn(req)
  79. ctxt.JSON(httpStatus, res)
  80. ctxt.Abort()
  81. } else {
  82. res := utils.E(9999, "未定义", nil)
  83. if i, ok := ctxt.Get(IsLogHTTPResponse); ok {
  84. if isLogHttpResponse, ok := i.(bool); ok && isLogHttpResponse {
  85. logger = logger.WithField("responseBody", `{"head":{"errcode":9999,"errmsg":"未定义"}}`)
  86. }
  87. }
  88. logger.
  89. WithCaller(5).
  90. WithField("tag", "Catch Exception").
  91. WithField("httpStatus", http.StatusBadRequest).
  92. WithField("errCode", 9999).
  93. WithField("errMsg", fmt.Sprintf("9999 %s", err)).
  94. Error(req)
  95. println(stack)
  96. ctxt.JSON(http.StatusBadRequest, res)
  97. ctxt.Abort()
  98. }
  99. }
  100. }()
  101. ctxt.Next()
  102. }
  103. }