55 lines
1.3 KiB
Go
55 lines
1.3 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
"runtime/debug"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// Recovery middleware personnalisé avec logging structuré
|
|
// Capture les panics et les log avec stack trace et contexte
|
|
func Recovery(logger *zap.Logger) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
requestID, _ := c.Get("request_id")
|
|
stack := debug.Stack()
|
|
|
|
// Construire les champs de log
|
|
logFields := []zap.Field{
|
|
zap.Any("error", err),
|
|
zap.String("path", c.Request.URL.Path),
|
|
zap.String("method", c.Request.Method),
|
|
zap.ByteString("stack", stack),
|
|
}
|
|
|
|
// Ajouter request_id si disponible
|
|
if requestID != nil {
|
|
if requestIDStr, ok := requestID.(string); ok {
|
|
logFields = append(logFields, zap.String("request_id", requestIDStr))
|
|
}
|
|
}
|
|
|
|
// Ajouter user_id si disponible
|
|
if userID, exists := c.Get("user_id"); exists {
|
|
logFields = append(logFields, zap.Any("user_id", userID))
|
|
}
|
|
|
|
logger.Error("Panic recovered", logFields...)
|
|
|
|
// Retourner une erreur 500 standardisée
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"error": gin.H{
|
|
"code": 9000,
|
|
"message": "Internal server error",
|
|
},
|
|
})
|
|
c.Abort()
|
|
}
|
|
}()
|
|
|
|
c.Next()
|
|
}
|
|
}
|