package middleware import ( "fmt" "log" "math/rand" "net/http" "runtime/debug" "time" "github.com/gin-gonic/gin" ) // ErrorHandler middleware for proper error handling func ErrorHandler() gin.HandlerFunc { return func(c *gin.Context) { defer func() { if err := recover(); err != nil { // Log the panic with stack trace log.Printf("Panic recovered: %v\n%s", err, debug.Stack()) c.Error(err.(error)) c.JSON(http.StatusInternalServerError, gin.H{ "error": "Internal server error", "message": "Something went wrong. Please try again later.", "request_id": c.GetString("request_id"), }) c.AbortWithStatus(http.StatusInternalServerError) } }() c.Next() } } // RequestID middleware for tracking requests func RequestID() gin.HandlerFunc { return func(c *gin.Context) { requestID := c.GetHeader("X-Request-ID") if requestID == "" { requestID = generateRequestID() } c.Set("request_id", requestID) c.Header("X-Request-ID", requestID) c.Next() } } func generateRequestID() string { // Simple request ID generation return "req_" + timestamp() + "_" + randomString(8) } func timestamp() string { return fmt.Sprintf("%d", time.Now().Unix()) } func randomString(length int) string { const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" b := make([]byte, length) for i := range b { b[i] = charset[rand.Intn(len(charset))] } return string(b) }