package errorx import ( "errors" "net/http" "github.com/gofiber/fiber/v3" "gorm.io/gorm" ) // ErrorHandler 错误处理器 type ErrorHandler struct{} // NewErrorHandler 创建错误处理器 func NewErrorHandler() *ErrorHandler { return &ErrorHandler{} } // Handle 处理错误并返回统一格式 func (h *ErrorHandler) Handle(err error) *AppError { if appErr, ok := err.(*AppError); ok { return appErr } // 处理 Fiber 错误 if fiberErr, ok := err.(*fiber.Error); ok { return h.handleFiberError(fiberErr) } // 处理 GORM 错误 if appErr := h.handleGormError(err); appErr != nil { return appErr } // 默认内部错误 return &AppError{ Code: ErrInternalError.Code, Message: err.Error(), StatusCode: http.StatusInternalServerError, originalErr: err, } } // handleFiberError 处理 Fiber 错误 func (h *ErrorHandler) handleFiberError(fiberErr *fiber.Error) *AppError { var appErr *AppError switch fiberErr.Code { case http.StatusBadRequest: appErr = ErrBadRequest case http.StatusUnauthorized: appErr = ErrUnauthorized case http.StatusForbidden: appErr = ErrForbidden case http.StatusNotFound: appErr = ErrRecordNotFound case http.StatusMethodNotAllowed: appErr = ErrUnsupportedMethod case http.StatusRequestEntityTooLarge: appErr = ErrRequestTooLarge case http.StatusTooManyRequests: appErr = ErrTooManyRequests default: appErr = ErrInternalError } return &AppError{ Code: appErr.Code, Message: fiberErr.Message, StatusCode: fiberErr.Code, originalErr: fiberErr, } } // handleGormError 处理 GORM 错误 func (h *ErrorHandler) handleGormError(err error) *AppError { if errors.Is(err, gorm.ErrRecordNotFound) { return &AppError{ Code: ErrRecordNotFound.Code, Message: ErrRecordNotFound.Message, StatusCode: ErrRecordNotFound.StatusCode, originalErr: err, } } if errors.Is(err, gorm.ErrDuplicatedKey) { return &AppError{ Code: ErrRecordDuplicated.Code, Message: ErrRecordDuplicated.Message, StatusCode: ErrRecordDuplicated.StatusCode, originalErr: err, } } if errors.Is(err, gorm.ErrInvalidTransaction) { return &AppError{ Code: ErrConcurrencyError.Code, Message: "事务无效", StatusCode: ErrConcurrencyError.StatusCode, originalErr: err, } } return nil }