1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- 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()
- }
- }
|