60 lines
1.5 KiB
Go
60 lines
1.5 KiB
Go
package middleware
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http/httputil"
|
|
"strings"
|
|
"time"
|
|
|
|
"ifms/pkg/errors"
|
|
"ifms/pkg/logging"
|
|
"ifms/pkg/util"
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type RecoveryConfig struct {
|
|
Skip int // default: 3
|
|
}
|
|
|
|
var DefaultRecoveryConfig = RecoveryConfig{
|
|
Skip: 3,
|
|
}
|
|
|
|
// Recovery from any panics and writes a 500 if there was one.
|
|
func Recovery() gin.HandlerFunc {
|
|
return RecoveryWithConfig(DefaultRecoveryConfig)
|
|
}
|
|
|
|
func RecoveryWithConfig(config RecoveryConfig) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
defer func() {
|
|
if rv := recover(); rv != nil {
|
|
ctx := c.Request.Context()
|
|
ctx = logging.NewTag(ctx, logging.TagKeyRecovery)
|
|
|
|
var fields []zap.Field
|
|
fields = append(fields, zap.Strings("error", []string{fmt.Sprintf("%v", rv)}))
|
|
fields = append(fields, zap.StackSkip("stack", config.Skip))
|
|
|
|
if gin.IsDebugging() {
|
|
httpRequest, _ := httputil.DumpRequest(c.Request, false)
|
|
headers := strings.Split(string(httpRequest), "\r\n")
|
|
for idx, header := range headers {
|
|
current := strings.Split(header, ":")
|
|
if current[0] == "Authorization" {
|
|
headers[idx] = current[0] + ": *"
|
|
}
|
|
}
|
|
fields = append(fields, zap.Strings("headers", headers))
|
|
}
|
|
|
|
logging.Context(ctx).Error(fmt.Sprintf("[Recovery] %s panic recovered", time.Now().Format("2006/01/02 - 15:04:05")), fields...)
|
|
util.ResError(c, errors.InternalServerError("", "Internal server error, please try again later"))
|
|
}
|
|
}()
|
|
|
|
c.Next()
|
|
}
|
|
}
|