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

13 KiB
Raw Permalink Blame History

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 (项目基础设施)

本阶段准备错误处理所需的基础代码结构。

任务列表

  • T001 审查现有错误处理代码 pkg/errors/errors.go 和 pkg/response/response.go
  • T002 审查现有中间件 internal/middleware/recover.go 实现
  • T003 确认 Request ID 中间件配置 (cmd/api/main.go 中的 requestid.New())

Phase 2: Foundational (核心基础组件)

本阶段实现所有用户故事依赖的核心组件:错误码定义和错误上下文提取。

阻塞关系: 必须在所有用户故事实施前完成

任务列表

  • T004 创建 pkg/errors/codes.go 定义完整错误码枚举 (CodeSuccess, Code1001-1009, Code2001-2006)
  • T005 在 pkg/errors/codes.go 中实现错误消息映射表 errorMessages (中文消息)
  • T006 在 pkg/errors/codes.go 中实现 GetHTTPStatus() 函数 (错误码 -> HTTP 状态码映射)
  • T007 在 pkg/errors/codes.go 中实现 GetMessage() 函数 (获取错误码对应的消息)
  • T008 扩展 pkg/errors/errors.go 中的 AppError 结构体,添加 HTTPStatus 字段
  • T009 [P] 在 pkg/errors/errors.go 中实现 AppError.WithHTTPStatus() 方法
  • T010 [P] 在 pkg/errors/errors.go 中实现 AppError.Error() 方法 (实现 error 接口)
  • T011 [P] 在 pkg/errors/errors.go 中实现 AppError.Unwrap() 方法 (支持错误链)
  • T012 创建 pkg/errors/context.go 定义 ErrorContext 结构体
  • T013 在 pkg/errors/context.go 中实现 FromFiberContext() 函数 (从 Fiber Ctx 提取错误上下文)
  • T014 在 pkg/errors/context.go 中实现 ErrorContext.ToLogFields() 方法 (转换为 Zap 日志字段)
  • T015 在 pkg/constants/constants.go 中添加 Request ID 相关常量 (如需补充)
  • T016 [P] 为 pkg/errors/codes.go 编写单元测试 (测试错误码映射函数)
  • T017 [P] 为 pkg/errors/context.go 编写单元测试 (测试上下文提取逻辑)

完成标志: 错误码和错误上下文组件可被其他模块导入使用


Phase 3: User Story 1 - 统一错误响应格式 (P1)

目标: 所有 API 错误返回统一的 JSON 格式,包含错误码、消息、时间戳

独立测试标准: 调用任意会产生错误的 API 端点,验证返回的 JSON 响应包含标准字段 (code, data, msg, timestamp),格式一致

任务列表

  • T018 [US1] 创建 pkg/errors/handler.go 实现 SafeErrorHandler() 函数 (返回 fiber.ErrorHandler)
  • T019 [US1] 在 pkg/errors/handler.go 中实现核心错误处理逻辑 handleError()
  • T020 [US1] 在 handleError() 中实现响应状态检查 (判断响应是否已发送)
  • T021 [US1] 在 handleError() 中实现错误类型分类 (*AppError, *fiber.Error, 其他 error)
  • T022 [US1] 在 handleError() 中实现错误消息脱敏逻辑 (5xx 返回通用消息)
  • T023 [US1] 在 handleError() 中集成 ErrorContext 提取和日志记录
  • T024 [US1] 在 handleError() 中实现统一 JSON 响应生成 (使用 fiber.Map)
  • T025 [US1] 在 handleError() 中设置响应 Header X-Request-ID
  • T026 [US1] 在 SafeErrorHandler() 中实现 defer + recover 保护机制 (防止 ErrorHandler 自身 panic)
  • T027 [US1] 更新 cmd/api/main.go 配置 Fiber ErrorHandler (使用 SafeErrorHandler)
  • T028 [US1] 为 pkg/errors/handler.go 编写单元测试 (测试不同错误类型的处理)
  • T029 [US1] 创建 tests/integration/error_handler_test.go 测试参数验证失败 -> 400 错误响应
  • T030 [US1] 在 tests/integration/error_handler_test.go 中测试资源未找到 -> 404 错误响应
  • T031 [US1] 在 tests/integration/error_handler_test.go 中测试认证失败 -> 401 错误响应
  • T032 [US1] 在 tests/integration/error_handler_test.go 中验证所有错误响应格式一致性

完成标志:

  • 所有 API 错误响应使用统一 JSON 格式
  • 集成测试覆盖常见错误场景 (400, 401, 404)
  • 错误消息脱敏,不暴露内部细节

Phase 4: User Story 2 - 系统稳定性保障(Panic 恢复) (P1)

目标: 捕获所有 panic 异常,防止服务崩溃,记录完整堆栈跟踪

独立测试标准: 创建测试端点触发 panic验证系统返回 500 错误响应,服务继续运行,其他端点正常工作,错误记录到日志

任务列表

  • T033 [US2] 审查现有 internal/middleware/recover.go 实现,确认是否需要调整
  • T034 [US2] 确保 recover 中间件在 Fiber 中间件链的正确位置注册 (ErrorHandler 之后)
  • T035 [US2] 在 recover 中间件中添加完整堆栈跟踪记录 (使用 runtime/debug.Stack())
  • T036 [US2] 在 recover 中间件中确保 panic 转换为可控的错误响应 (返回 AppError)
  • T037 [US2] 验证 recover 中间件与 ErrorHandler 的集成 (panic -> AppError -> ErrorHandler)
  • T038 [US2] 为 internal/middleware/recover.go 编写单元测试 (测试 panic 捕获)
  • T039 [US2] 在 tests/integration/error_handler_test.go 中创建测试端点触发 panic
  • T040 [US2] 在 tests/integration/error_handler_test.go 中测试 panic 恢复后服务继续运行
  • T041 [US2] 在 tests/integration/error_handler_test.go 中测试并发场景下的 panic 处理 (多个请求)
  • T042 [US2] 在 tests/integration/error_handler_test.go 中验证 panic 时的堆栈跟踪记录
    • 验证堆栈跟踪完整性:确保日志包含文件名、行号、函数名
    • 验证堆栈深度:检查是否包含从 panic 发生点到 recover 捕获点的完整调用链
    • 验证格式可读性:堆栈信息应便于开发人员快速定位问题

完成标志:

  • 系统能捕获 100% 的 panic
  • 单个请求 panic 不影响其他请求
  • 日志包含完整的堆栈跟踪信息

Phase 5: User Story 3 - 业务错误分类处理 (P2)

目标: 区分不同类型的错误 (客户端错误、服务端错误),记录适当的日志级别,返回相应的 HTTP 状态码

独立测试标准: 触发不同类型的错误 (验证失败、权限不足、数据库错误),验证错误分类正确,日志级别匹配 (客户端错误 Warn服务端错误 Error)HTTP 状态码正确

任务列表

  • T043 [P] [US3] 在 pkg/errors/codes.go 中实现 GetLogLevel() 函数 (错误码 -> 日志级别映射)
  • T044 [US3] 在 pkg/errors/handler.go 中集成 GetLogLevel(),根据错误类型记录不同日志级别
  • T045 [P] [US3] 在 tests/integration/error_handler_test.go 中测试参数验证失败 -> Warn 级别日志
  • T046 [P] [US3] 在 tests/integration/error_handler_test.go 中测试权限不足 -> Warn 级别日志
  • T047 [P] [US3] 在 tests/integration/error_handler_test.go 中测试数据库错误 -> Error 级别日志
  • T048 [US3] 在 tests/integration/error_handler_test.go 中验证敏感信息隐藏 (数据库错误不暴露 SQL)
  • T049 [US3] 在 tests/integration/error_handler_test.go 中测试限流错误 -> 429 响应
  • 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验证能找到完整的请求上下文 (路径、方法、参数) 和错误详情

任务列表

  • T051 [P] [US4] 在 pkg/errors/context.go 中完善 ErrorContext 字段 (确保包含所有调试信息)
  • T052 [US4] 在 pkg/errors/handler.go 中确保错误日志包含所有 ErrorContext 字段
  • T053 [US4] 在 pkg/errors/handler.go 中添加请求参数记录 (Query 和 Body限制 50KB)
  • T054 [US4] 在 tests/integration/error_handler_test.go 中测试错误日志完整性 (包含 Request ID)
  • T055 [US4] 在 tests/integration/error_handler_test.go 中测试请求上下文记录 (路径、方法、参数)
  • T056 [US4] 在 tests/integration/error_handler_test.go 中测试 panic 堆栈跟踪记录 (指明 panic 位置)
  • T057 [US4] 在 tests/integration/error_handler_test.go 中测试使用 Request ID 追踪请求流程

完成标志:

  • 所有错误日志包含 Request ID
  • 日志包含完整的请求上下文 (路径、方法、参数)
  • Panic 日志包含完整的堆栈跟踪

Phase 7: Polish & Cross-Cutting Concerns

本阶段完善文档、性能优化和最终验证。

任务列表

  • T058 运行所有单元测试并验证覆盖率 > 90% (pkg/errors/ 包)
  • T059 运行所有集成测试并验证所有场景通过
  • T060 运行性能基准测试,验证错误处理延迟 < 1ms (P95)
  • T061 在高并发场景下测试错误处理 (1000+ 并发请求)
  • T062 [P] 创建 docs/003-error-handling/功能总结.md (功能概述、核心实现、技术要点)
  • T063 [P] 创建 docs/003-error-handling/使用指南.md (如何使用错误处理机制)
  • T064 [P] 创建 docs/003-error-handling/架构说明.md (错误处理架构设计,可选)
  • T065 更新 README.md 添加错误处理功能的简短描述 (2-3 句话)
  • T066 更新 CLAUDE.md 添加错误处理相关技术栈信息 (如需)
  • T067 代码审查:验证所有注释和日志消息使用中文
  • T068 代码审查:验证没有硬编码的魔术数字或字符串 (3+ 次出现必须定义为常量)
  • T069 运行 go fmtgolangci-lint 检查代码质量
  • 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 开始执行任务