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

266 lines
13 KiB
Markdown
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.
# Tasks: Fiber 错误处理集成
**Feature**: 003-error-handling
**Generated**: 2025-11-14
**Status**: Ready for Implementation
## 概述
本文档按用户故事组织实施任务,每个用户故事代表一个独立可测试的增量功能。
**技术栈**: Go 1.25.4, Fiber v2, Zap, GORM, Asynq, PostgreSQL 14+, Redis 6.0+
**测试策略**: 单元测试 + 集成测试,目标覆盖率 90%+
## 实施策略
- **MVP 范围**: User Story 1 + User Story 2 (P1 优先级)
- **增量交付**: 每完成一个用户故事即可独立测试和部署
- **并行机会**: 标记 [P] 的任务可并行执行
---
## Phase 1: Setup (项目基础设施)
本阶段准备错误处理所需的基础代码结构。
### 任务列表
- [X] T001 审查现有错误处理代码 pkg/errors/errors.go 和 pkg/response/response.go
- [X] T002 审查现有中间件 internal/middleware/recover.go 实现
- [X] T003 确认 Request ID 中间件配置 (cmd/api/main.go 中的 requestid.New())
---
## Phase 2: Foundational (核心基础组件)
本阶段实现所有用户故事依赖的核心组件:错误码定义和错误上下文提取。
**阻塞关系**: 必须在所有用户故事实施前完成
### 任务列表
- [X] T004 创建 pkg/errors/codes.go 定义完整错误码枚举 (CodeSuccess, Code1001-1009, Code2001-2006)
- [X] T005 在 pkg/errors/codes.go 中实现错误消息映射表 errorMessages (中文消息)
- [X] T006 在 pkg/errors/codes.go 中实现 GetHTTPStatus() 函数 (错误码 -> HTTP 状态码映射)
- [X] T007 在 pkg/errors/codes.go 中实现 GetMessage() 函数 (获取错误码对应的消息)
- [X] T008 扩展 pkg/errors/errors.go 中的 AppError 结构体,添加 HTTPStatus 字段
- [X] T009 [P] 在 pkg/errors/errors.go 中实现 AppError.WithHTTPStatus() 方法
- [X] T010 [P] 在 pkg/errors/errors.go 中实现 AppError.Error() 方法 (实现 error 接口)
- [X] T011 [P] 在 pkg/errors/errors.go 中实现 AppError.Unwrap() 方法 (支持错误链)
- [X] T012 创建 pkg/errors/context.go 定义 ErrorContext 结构体
- [X] T013 在 pkg/errors/context.go 中实现 FromFiberContext() 函数 (从 Fiber Ctx 提取错误上下文)
- [X] T014 在 pkg/errors/context.go 中实现 ErrorContext.ToLogFields() 方法 (转换为 Zap 日志字段)
- [X] T015 在 pkg/constants/constants.go 中添加 Request ID 相关常量 (如需补充)
- [X] T016 [P] 为 pkg/errors/codes.go 编写单元测试 (测试错误码映射函数)
- [X] T017 [P] 为 pkg/errors/context.go 编写单元测试 (测试上下文提取逻辑)
**完成标志**: 错误码和错误上下文组件可被其他模块导入使用
---
## Phase 3: User Story 1 - 统一错误响应格式 (P1)
**目标**: 所有 API 错误返回统一的 JSON 格式,包含错误码、消息、时间戳
**独立测试标准**: 调用任意会产生错误的 API 端点,验证返回的 JSON 响应包含标准字段 (code, data, msg, timestamp),格式一致
### 任务列表
- [X] T018 [US1] 创建 pkg/errors/handler.go 实现 SafeErrorHandler() 函数 (返回 fiber.ErrorHandler)
- [X] T019 [US1] 在 pkg/errors/handler.go 中实现核心错误处理逻辑 handleError()
- [X] T020 [US1] 在 handleError() 中实现响应状态检查 (判断响应是否已发送)
- [X] T021 [US1] 在 handleError() 中实现错误类型分类 (*AppError, *fiber.Error, 其他 error)
- [X] T022 [US1] 在 handleError() 中实现错误消息脱敏逻辑 (5xx 返回通用消息)
- [X] T023 [US1] 在 handleError() 中集成 ErrorContext 提取和日志记录
- [X] T024 [US1] 在 handleError() 中实现统一 JSON 响应生成 (使用 fiber.Map)
- [X] T025 [US1] 在 handleError() 中设置响应 Header X-Request-ID
- [X] T026 [US1] 在 SafeErrorHandler() 中实现 defer + recover 保护机制 (防止 ErrorHandler 自身 panic)
- [X] T027 [US1] 更新 cmd/api/main.go 配置 Fiber ErrorHandler (使用 SafeErrorHandler)
- [X] T028 [US1] 为 pkg/errors/handler.go 编写单元测试 (测试不同错误类型的处理)
- [X] T029 [US1] 创建 tests/integration/error_handler_test.go 测试参数验证失败 -> 400 错误响应
- [X] T030 [US1] 在 tests/integration/error_handler_test.go 中测试资源未找到 -> 404 错误响应
- [X] T031 [US1] 在 tests/integration/error_handler_test.go 中测试认证失败 -> 401 错误响应
- [X] T032 [US1] 在 tests/integration/error_handler_test.go 中验证所有错误响应格式一致性
**完成标志**:
- 所有 API 错误响应使用统一 JSON 格式
- 集成测试覆盖常见错误场景 (400, 401, 404)
- 错误消息脱敏,不暴露内部细节
---
## Phase 4: User Story 2 - 系统稳定性保障(Panic 恢复) (P1)
**目标**: 捕获所有 panic 异常,防止服务崩溃,记录完整堆栈跟踪
**独立测试标准**: 创建测试端点触发 panic验证系统返回 500 错误响应,服务继续运行,其他端点正常工作,错误记录到日志
### 任务列表
- [X] T033 [US2] 审查现有 internal/middleware/recover.go 实现,确认是否需要调整
- [X] T034 [US2] 确保 recover 中间件在 Fiber 中间件链的正确位置注册 (ErrorHandler 之后)
- [X] T035 [US2] 在 recover 中间件中添加完整堆栈跟踪记录 (使用 runtime/debug.Stack())
- [X] T036 [US2] 在 recover 中间件中确保 panic 转换为可控的错误响应 (返回 AppError)
- [X] T037 [US2] 验证 recover 中间件与 ErrorHandler 的集成 (panic -> AppError -> ErrorHandler)
- [X] T038 [US2] 为 internal/middleware/recover.go 编写单元测试 (测试 panic 捕获)
- [X] T039 [US2] 在 tests/integration/error_handler_test.go 中创建测试端点触发 panic
- [X] T040 [US2] 在 tests/integration/error_handler_test.go 中测试 panic 恢复后服务继续运行
- [X] T041 [US2] 在 tests/integration/error_handler_test.go 中测试并发场景下的 panic 处理 (多个请求)
- [X] T042 [US2] 在 tests/integration/error_handler_test.go 中验证 panic 时的堆栈跟踪记录
- **验证堆栈跟踪完整性**:确保日志包含文件名、行号、函数名
- **验证堆栈深度**:检查是否包含从 panic 发生点到 recover 捕获点的完整调用链
- **验证格式可读性**:堆栈信息应便于开发人员快速定位问题
**完成标志**:
- 系统能捕获 100% 的 panic
- 单个请求 panic 不影响其他请求
- 日志包含完整的堆栈跟踪信息
---
## Phase 5: User Story 3 - 业务错误分类处理 (P2)
**目标**: 区分不同类型的错误 (客户端错误、服务端错误),记录适当的日志级别,返回相应的 HTTP 状态码
**独立测试标准**: 触发不同类型的错误 (验证失败、权限不足、数据库错误),验证错误分类正确,日志级别匹配 (客户端错误 Warn服务端错误 Error)HTTP 状态码正确
### 任务列表
- [X] T043 [P] [US3] 在 pkg/errors/codes.go 中实现 GetLogLevel() 函数 (错误码 -> 日志级别映射)
- [X] T044 [US3] 在 pkg/errors/handler.go 中集成 GetLogLevel(),根据错误类型记录不同日志级别
- [X] T045 [P] [US3] 在 tests/integration/error_handler_test.go 中测试参数验证失败 -> Warn 级别日志
- [X] T046 [P] [US3] 在 tests/integration/error_handler_test.go 中测试权限不足 -> Warn 级别日志
- [X] T047 [P] [US3] 在 tests/integration/error_handler_test.go 中测试数据库错误 -> Error 级别日志
- [X] T048 [US3] 在 tests/integration/error_handler_test.go 中验证敏感信息隐藏 (数据库错误不暴露 SQL)
- [X] T049 [US3] 在 tests/integration/error_handler_test.go 中测试限流错误 -> 429 响应
- [X] T050 [US3] 在 tests/integration/error_handler_test.go 中测试服务不可用 -> 503 响应
**完成标志**:
- 客户端错误 (1xxx) 记录为 Warn 级别,返回 4xx 状态码
- 服务端错误 (2xxx) 记录为 Error 级别,返回 5xx 状态码
- 敏感信息不暴露给客户端
---
## Phase 6: User Story 4 - 错误追踪和调试支持 (P3)
**目标**: 错误日志包含完整的请求上下文 (Request ID, 路径, 参数),便于快速定位和排查问题
**独立测试标准**: 触发一个错误,在日志中搜索 request_id验证能找到完整的请求上下文 (路径、方法、参数) 和错误详情
### 任务列表
- [X] T051 [P] [US4] 在 pkg/errors/context.go 中完善 ErrorContext 字段 (确保包含所有调试信息)
- [X] T052 [US4] 在 pkg/errors/handler.go 中确保错误日志包含所有 ErrorContext 字段
- [X] T053 [US4] 在 pkg/errors/handler.go 中添加请求参数记录 (Query 和 Body限制 50KB)
- [X] T054 [US4] 在 tests/integration/error_handler_test.go 中测试错误日志完整性 (包含 Request ID)
- [X] T055 [US4] 在 tests/integration/error_handler_test.go 中测试请求上下文记录 (路径、方法、参数)
- [X] T056 [US4] 在 tests/integration/error_handler_test.go 中测试 panic 堆栈跟踪记录 (指明 panic 位置)
- [X] T057 [US4] 在 tests/integration/error_handler_test.go 中测试使用 Request ID 追踪请求流程
**完成标志**:
- 所有错误日志包含 Request ID
- 日志包含完整的请求上下文 (路径、方法、参数)
- Panic 日志包含完整的堆栈跟踪
---
## Phase 7: Polish & Cross-Cutting Concerns
本阶段完善文档、性能优化和最终验证。
### 任务列表
- [X] T058 运行所有单元测试并验证覆盖率 > 90% (pkg/errors/ 包)
- [X] T059 运行所有集成测试并验证所有场景通过
- [X] T060 运行性能基准测试,验证错误处理延迟 < 1ms (P95)
- [X] T061 在高并发场景下测试错误处理 (1000+ 并发请求)
- [X] T062 [P] 创建 docs/003-error-handling/功能总结.md (功能概述、核心实现、技术要点)
- [X] T063 [P] 创建 docs/003-error-handling/使用指南.md (如何使用错误处理机制)
- [X] T064 [P] 创建 docs/003-error-handling/架构说明.md (错误处理架构设计,可选)
- [X] T065 更新 README.md 添加错误处理功能的简短描述 (2-3 句话)
- [X] T066 更新 CLAUDE.md 添加错误处理相关技术栈信息 (如需)
- [X] T067 代码审查:验证所有注释和日志消息使用中文
- [X] T068 代码审查:验证没有硬编码的魔术数字或字符串 (3+ 次出现必须定义为常量)
- [X] T069 运行 `go fmt``golangci-lint` 检查代码质量
- [X] T070 最终验证:所有 Success Criteria (SC-001 到 SC-008) 已满足
---
## 依赖关系图
```
Setup (T001-T003)
Foundational (T004-T017) ← 阻塞所有用户故事
├→ User Story 1 (T018-T032) [P1] ← MVP 核心
├→ User Story 2 (T033-T042) [P1] ← MVP 核心
├→ User Story 3 (T043-T050) [P2] ← 依赖 US1, US2
├→ User Story 4 (T051-T057) [P3] ← 依赖 US1, US2
Polish (T058-T070) ← 依赖所有用户故事完成
```
**关键路径**: Setup → Foundational → US1 → US2 → US3 → US4 → Polish
**并行机会**:
- US1 阶段: T028 单元测试可与 T029-T032 集成测试并行
- US2 阶段: T038 单元测试可与 T039-T042 集成测试并行
- US3 阶段: T045, T046, T047 测试任务可并行执行
- US4 阶段: T054-T057 测试任务可并行执行
- Polish 阶段: T062, T063, T064 文档编写可并行执行
---
## 任务统计
- **总任务数**: 70 个任务
- **Setup**: 3 个任务
- **Foundational**: 14 个任务
- **User Story 1 (P1)**: 15 个任务
- **User Story 2 (P1)**: 10 个任务
- **User Story 3 (P2)**: 8 个任务
- **User Story 4 (P3)**: 7 个任务
- **Polish**: 13 个任务
- **可并行任务**: 18 个任务 (标记 [P])
**MVP 范围**: T001-T042 (Setup + Foundational + US1 + US2) = 42 个任务
**预估时间**:
- MVP (US1 + US2): 2-3 天
- 完整功能 (US1-US4): 4-5 天
- 包含文档和优化: 5-6 天
---
## 实施建议
1. **优先完成 MVP**: 先实现 US1 和 US2 (P1 优先级),确保核心错误处理和 panic 恢复功能可用
2. **增量测试**: 每完成一个用户故事立即进行集成测试,确保功能正确
3. **并行执行**: 利用标记 [P] 的任务并行开发,提高效率
4. **代码审查**: 在进入下一个用户故事前,审查当前代码质量
5. **性能验证**: 在 Polish 阶段进行性能测试,确保错误处理延迟 < 1ms
---
## 成功标准验证
完成所有任务后,验证以下成功标准:
-**SC-001**: 系统能够捕获 100% 的 panic (US2)
-**SC-002**: 所有 API 错误响应格式一致 (US1)
-**SC-003**: 错误日志记录率 100% (US1, US4)
-**SC-004**: 客户端能通过错误码识别错误类型 (US1, US3)
-**SC-005**: 5 分钟内通过 Request ID 定位错误 (US4)
-**SC-006**: 错误处理延迟 < 1ms (所有 US)
-**SC-007**: 错误响应不包含敏感信息 (US1, US3)
-**SC-008**: 高并发下错误处理不成为瓶颈 (US2, Polish)
---
**文档版本**: 1.0
**最后更新**: 2025-11-14
**下一步**: 运行 `/speckit.implement` 开始执行任务