Files
huang fb83c9a706 feat: 实现统一错误处理系统 (003-error-handling)
- 新增统一错误码定义和管理 (pkg/errors/codes.go)
- 新增全局错误处理器和中间件 (pkg/errors/handler.go, internal/middleware/error_handler.go)
- 新增错误上下文管理 (pkg/errors/context.go)
- 增强 Panic 恢复中间件 (internal/middleware/recover.go)
- 新增完整的单元测试和集成测试
- 新增功能文档 (docs/003-error-handling/)
- 新增功能规范 (specs/003-error-handling/)
- 更新 CLAUDE.md 和 README.md
2025-11-15 12:17:44 +08:00

56 lines
1.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package middleware
import (
"fmt"
"runtime/debug"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
)
// Recover 创建自定义 panic 恢复中间件
// panic 会被转换为 AppError 并传递给 ErrorHandler 统一处理
func Recover(logger *zap.Logger) fiber.Handler {
return func(c *fiber.Ctx) error {
defer func() {
if r := recover(); r != nil {
// 获取请求 ID
requestID := ""
if rid := c.Locals(constants.ContextKeyRequestID); rid != nil {
requestID = rid.(string)
}
// 捕获堆栈跟踪
stack := debug.Stack()
// 记录 panic 信息(包含完整堆栈)
logger.Error("Panic 已恢复",
zap.String("request_id", requestID),
zap.String("method", c.Method()),
zap.String("path", c.Path()),
zap.Any("panic", r),
zap.String("stack", string(stack)),
)
// 将 panic 转换为 AppError
// 注意:这里不直接返回响应,而是返回错误让 ErrorHandler 处理
// 但由于我们在 defer 中,需要通过 c.Next() 返回错误
panicErr := errors.Wrap(
errors.CodeInternalError,
fmt.Sprintf("服务发生异常: %v", r),
fmt.Errorf("panic: %v", r),
)
// 直接调用 ErrorHandler通过返回错误
// Fiber 会将这个错误传递给 ErrorHandler
_ = c.App().Config().ErrorHandler(c, panicErr)
}
}()
return c.Next()
}
}