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
This commit is contained in:
265
specs/003-error-handling/tasks.md
Normal file
265
specs/003-error-handling/tasks.md
Normal file
@@ -0,0 +1,265 @@
|
||||
# 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` 开始执行任务
|
||||
Reference in New Issue
Block a user