package middleware import ( "net/http" "github.com/gin-gonic/gin" ) // ErrorHandlerConfig holds the configuration for the error handler middleware type ErrorHandlerConfig struct { TimeFormat string TimeZone string } // DefaultErrorHandlerConfig returns the default error handler configuration func DefaultErrorHandlerConfig() *ErrorHandlerConfig { return &ErrorHandlerConfig{ TimeFormat: "2006/01/02 - 15:04:05", TimeZone: "UTC", } } // ErrorHandler returns a Gin middleware handler for centralized error handling func ErrorHandler() gin.HandlerFunc { return ErrorHandlerWithConfig(DefaultErrorHandlerConfig()) } // ErrorHandlerWithConfig returns a Gin middleware handler for centralized error handling with custom configuration func ErrorHandlerWithConfig(config *ErrorHandlerConfig) gin.HandlerFunc { return func(c *gin.Context) { c.Next() // Check if there were any errors if len(c.Errors) > 0 { err := c.Errors.Last() // Determine the status code statusCode := http.StatusInternalServerError if gin.Mode() != gin.ReleaseMode { // In development mode, return detailed error information c.JSON(http.StatusInternalServerError, gin.H{ "error": "internal server error", "message": err.Error(), "details": c.Errors, }) return } // In production mode, return a generic error message c.JSON(statusCode, gin.H{ "error": "internal server error", }) } } } // ErrorResponse represents a standard error response type ErrorResponse struct { Error string `json:"error"` Code string `json:"code,omitempty"` Details map[string]string `json:"details,omitempty"` } // NewErrorResponse creates a new error response func NewErrorResponse(error string, code string, details map[string]string) *ErrorResponse { return &ErrorResponse{ Error: error, Code: code, Details: details, } } // BadRequest creates a 400 Bad Request response func BadRequest(c *gin.Context, message string) { c.JSON(http.StatusBadRequest, gin.H{ "error": message, }) } // Unauthorized creates a 401 Unauthorized response func Unauthorized(c *gin.Context, message string) { c.JSON(http.StatusUnauthorized, gin.H{ "error": message, }) } // Forbidden creates a 403 Forbidden response func Forbidden(c *gin.Context, message string) { c.JSON(http.StatusForbidden, gin.H{ "error": message, }) } // NotFound creates a 404 Not Found response func NotFound(c *gin.Context, message string) { c.JSON(http.StatusNotFound, gin.H{ "error": message, }) } // InternalServerError creates a 500 Internal Server Error response func InternalServerError(c *gin.Context, message string) { c.JSON(http.StatusInternalServerError, gin.H{ "error": message, }) } // ValidationError creates a response for validation errors func ValidationError(c *gin.Context, errors map[string]string) { c.JSON(http.StatusBadRequest, gin.H{ "error": "validation failed", "details": errors, }) }