package middleware import ( "fmt" "net/http" "runtime/debug" "git.linuxforward.com/byom/byom-core/logger" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" ) // Recovery returns a middleware that recovers from panics and logs the stack trace func Recovery(log *logrus.Logger) gin.HandlerFunc { recoveryLogger := logger.NewLogger("recovery") return func(c *gin.Context) { defer func() { if err := recover(); err != nil { // Get request ID if available requestID := c.GetString(RequestIDKey) if requestID == "" { requestID = "no-request-id" } // Get stack trace stack := string(debug.Stack()) // Add request ID to logger reqLogger := logger.WithRequestID(recoveryLogger, requestID) // Log the panic with context reqLogger.WithFields(logrus.Fields{ "error": fmt.Sprintf("%v", err), "stack": stack, "method": c.Request.Method, "path": c.Request.URL.Path, "client_ip": c.ClientIP(), }).Error("Panic recovered") // Return a 500 error to the client c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{ "error": "Internal server error", "code": "INTERNAL_SERVER_ERROR", }) } }() c.Next() } }