feat: 添加应用错误处理结构及预定义错误码

This commit is contained in:
Rogee
2025-09-11 11:44:26 +08:00
parent bfcc1327d2
commit ced4202dc9
9 changed files with 645 additions and 161 deletions

View File

@@ -0,0 +1,106 @@
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
}