| |
| |
| package middleware |
|
|
| import ( |
| "net/http" |
|
|
| "github.com/gin-gonic/gin" |
| "github.com/router-for-me/CLIProxyAPI/v6/internal/domain/errors" |
| ) |
|
|
| |
| type ErrorResponse struct { |
| Success bool `json:"success"` |
| Error *APIError `json:"error,omitempty"` |
| RequestID string `json:"request_id,omitempty"` |
| } |
|
|
| |
| type APIError struct { |
| Code string `json:"code"` |
| Message string `json:"message"` |
| Field string `json:"field,omitempty"` |
| } |
|
|
| |
| |
| |
| func ErrorHandlerMiddleware() gin.HandlerFunc { |
| return func(c *gin.Context) { |
| c.Next() |
|
|
| |
| if len(c.Errors) > 0 { |
| err := c.Errors.Last() |
| handleError(c, err) |
| } |
| } |
| } |
|
|
| |
| func handleError(c *gin.Context, err *gin.Error) { |
| requestID := GetCorrelationID(c) |
| |
| |
| if domainErr, ok := err.Err.(*errors.DomainError); ok { |
| statusCode := domainErr.HTTPStatusCode() |
| apiErr := &APIError{ |
| Code: string(domainErr.Code), |
| Message: domainErr.Message, |
| } |
| |
| if domainErr.Details != nil { |
| if field, ok := domainErr.Details["field"].(string); ok { |
| apiErr.Field = field |
| } |
| } |
| response := ErrorResponse{ |
| Success: false, |
| RequestID: requestID, |
| Error: apiErr, |
| } |
| c.JSON(statusCode, response) |
| return |
| } |
|
|
| |
| switch err.Type { |
| case gin.ErrorTypeBind: |
| c.JSON(http.StatusBadRequest, ErrorResponse{ |
| Success: false, |
| RequestID: requestID, |
| Error: &APIError{ |
| Code: "INVALID_INPUT", |
| Message: "Invalid request format: " + err.Err.Error(), |
| }, |
| }) |
| case gin.ErrorTypeRender: |
| c.JSON(http.StatusInternalServerError, ErrorResponse{ |
| Success: false, |
| RequestID: requestID, |
| Error: &APIError{ |
| Code: "RENDER_ERROR", |
| Message: "Failed to render response", |
| }, |
| }) |
| default: |
| c.JSON(http.StatusInternalServerError, ErrorResponse{ |
| Success: false, |
| RequestID: requestID, |
| Error: &APIError{ |
| Code: "INTERNAL_ERROR", |
| Message: "An internal error occurred", |
| }, |
| }) |
| } |
| } |
|
|
| |
| func AbortWithDomainError(c *gin.Context, err *errors.DomainError) { |
| c.Error(err) |
| c.Abort() |
| } |
|
|
| |
| func RespondWithError(c *gin.Context, err error) { |
| c.Error(err) |
| } |
|
|