| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| package middleware |
|
|
| import ( |
| "github.com/libaxuan/cursor2api-go/models" |
| "net/http" |
|
|
| "github.com/gin-gonic/gin" |
| "github.com/sirupsen/logrus" |
| ) |
|
|
| |
| type CursorWebError struct { |
| StatusCode int `json:"status_code"` |
| Message string `json:"message"` |
| } |
|
|
| |
| func (e *CursorWebError) Error() string { |
| return e.Message |
| } |
|
|
| |
| func NewCursorWebError(statusCode int, message string) *CursorWebError { |
| return &CursorWebError{ |
| StatusCode: statusCode, |
| Message: message, |
| } |
| } |
|
|
| |
| func ErrorHandler() gin.HandlerFunc { |
| return func(c *gin.Context) { |
| c.Next() |
|
|
| |
| if len(c.Errors) > 0 { |
| err := c.Errors.Last().Err |
| handleError(c, err) |
| } |
| } |
| } |
|
|
| |
| func HandleError(c *gin.Context, err error) { |
| handleError(c, err) |
| } |
|
|
| |
| func handleError(c *gin.Context, err error) { |
| |
| if c.Writer.Written() { |
| return |
| } |
|
|
| logrus.WithError(err).Error("API error occurred") |
|
|
| switch e := err.(type) { |
| case *CursorWebError: |
| |
| errorResponse := models.NewErrorResponse( |
| e.Message, |
| "cursor_web_error", |
| "", |
| ) |
| c.JSON(e.StatusCode, errorResponse) |
|
|
| case *gin.Error: |
| |
| statusCode := http.StatusBadRequest |
| if e.Type == gin.ErrorTypePublic { |
| statusCode = http.StatusInternalServerError |
| } |
|
|
| errorResponse := models.NewErrorResponse( |
| e.Error(), |
| "validation_error", |
| "invalid_request", |
| ) |
| c.JSON(statusCode, errorResponse) |
|
|
| case *RequestValidationError: |
| errorResponse := models.NewErrorResponse( |
| e.Message, |
| "invalid_request_error", |
| e.Code, |
| ) |
| c.JSON(http.StatusBadRequest, errorResponse) |
|
|
| default: |
| |
| errorResponse := models.NewErrorResponse( |
| "Internal server error", |
| "internal_error", |
| "", |
| ) |
| c.JSON(http.StatusInternalServerError, errorResponse) |
| } |
| } |
|
|
| |
| type RequestValidationError struct { |
| Message string `json:"message"` |
| Code string `json:"code,omitempty"` |
| } |
|
|
| |
| func (e *RequestValidationError) Error() string { |
| return e.Message |
| } |
|
|
| |
| func NewRequestValidationError(message, code string) *RequestValidationError { |
| return &RequestValidationError{ |
| Message: message, |
| Code: code, |
| } |
| } |
|
|
| |
| func RecoveryHandler() gin.HandlerFunc { |
| return gin.CustomRecovery(func(c *gin.Context, recovered interface{}) { |
| logrus.WithField("panic", recovered).Error("Panic occurred") |
|
|
| if c.Writer.Written() { |
| return |
| } |
|
|
| errorResponse := models.NewErrorResponse( |
| "Internal server error", |
| "panic_error", |
| "", |
| ) |
| c.JSON(http.StatusInternalServerError, errorResponse) |
| }) |
| } |
|
|
| |
| type ValidationError struct { |
| Field string `json:"field"` |
| Message string `json:"message"` |
| } |
|
|
| |
| type MultipleValidationError struct { |
| Errors []ValidationError `json:"errors"` |
| } |
|
|
| |
| func (e *MultipleValidationError) Error() string { |
| return "validation failed" |
| } |
|
|
| |
| func NewValidationError(field, message string) *ValidationError { |
| return &ValidationError{ |
| Field: field, |
| Message: message, |
| } |
| } |
|
|
| |
| type AuthenticationError struct { |
| Message string `json:"message"` |
| } |
|
|
| |
| func (e *AuthenticationError) Error() string { |
| return e.Message |
| } |
|
|
| |
| func NewAuthenticationError(message string) *AuthenticationError { |
| return &AuthenticationError{ |
| Message: message, |
| } |
| } |
|
|
| |
| type RateLimitError struct { |
| Message string `json:"message"` |
| RetryAfter int `json:"retry_after"` |
| } |
|
|
| |
| func (e *RateLimitError) Error() string { |
| return e.Message |
| } |
|
|
| |
| func NewRateLimitError(message string, retryAfter int) *RateLimitError { |
| return &RateLimitError{ |
| Message: message, |
| RetryAfter: retryAfter, |
| } |
| } |
|
|