cursor / middleware /error.go
cacode's picture
Upload 48 files
1766992 verified
// Copyright (c) 2025-2026 libaxuan
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
package middleware
import (
"github.com/libaxuan/cursor2api-go/models"
"net/http"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
// CursorWebError Cursor Web API错误
type CursorWebError struct {
StatusCode int `json:"status_code"`
Message string `json:"message"`
}
// Error 实现error接口
func (e *CursorWebError) Error() string {
return e.Message
}
// NewCursorWebError 创建新的CursorWebError
func NewCursorWebError(statusCode int, message string) *CursorWebError {
return &CursorWebError{
StatusCode: statusCode,
Message: message,
}
}
// ErrorHandler 全局错误处理中间件
func ErrorHandler() gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
// 处理上下文中的错误
if len(c.Errors) > 0 {
err := c.Errors.Last().Err
handleError(c, err)
}
}
}
// HandleError 处理错误并返回适当的响应
func HandleError(c *gin.Context, err error) {
handleError(c, err)
}
// handleError 内部错误处理逻辑
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:
// 处理Cursor Web错误
errorResponse := models.NewErrorResponse(
e.Message,
"cursor_web_error",
"",
)
c.JSON(e.StatusCode, errorResponse)
case *gin.Error:
// 处理Gin绑定错误
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)
}
}
// RequestValidationError 请求参数验证错误
type RequestValidationError struct {
Message string `json:"message"`
Code string `json:"code,omitempty"`
}
// Error 实现 error 接口
func (e *RequestValidationError) Error() string {
return e.Message
}
// NewRequestValidationError 创建请求参数验证错误
func NewRequestValidationError(message, code string) *RequestValidationError {
return &RequestValidationError{
Message: message,
Code: code,
}
}
// RecoveryHandler 自定义恢复中间件
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)
})
}
// ValidationError 验证错误
type ValidationError struct {
Field string `json:"field"`
Message string `json:"message"`
}
// MultipleValidationError 多个验证错误
type MultipleValidationError struct {
Errors []ValidationError `json:"errors"`
}
// Error 实现error接口
func (e *MultipleValidationError) Error() string {
return "validation failed"
}
// NewValidationError 创建验证错误
func NewValidationError(field, message string) *ValidationError {
return &ValidationError{
Field: field,
Message: message,
}
}
// AuthenticationError 认证错误
type AuthenticationError struct {
Message string `json:"message"`
}
// Error 实现error接口
func (e *AuthenticationError) Error() string {
return e.Message
}
// NewAuthenticationError 创建认证错误
func NewAuthenticationError(message string) *AuthenticationError {
return &AuthenticationError{
Message: message,
}
}
// RateLimitError 限流错误
type RateLimitError struct {
Message string `json:"message"`
RetryAfter int `json:"retry_after"`
}
// Error 实现error接口
func (e *RateLimitError) Error() string {
return e.Message
}
// NewRateLimitError 创建限流错误
func NewRateLimitError(message string, retryAfter int) *RateLimitError {
return &RateLimitError{
Message: message,
RetryAfter: retryAfter,
}
}