Files
junhong_cmp_fiber/openspec/specs/error-code-validation/spec.md
huang 6821e5abcf
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 4m36s
refactor: 统一错误消息数据源,优化错误码与映射表管理
主要改动:
- 改造 errors.New() 和 Wrap() 函数签名为可变参数,优先使用 errorMessages 映射表
- 添加 allErrorCodes 注册表和 init() 启动时校验,确保错误码与映射表一致
- 添加 TestAllCodesHaveMessages 和 TestNoOrphanMessages 测试防止映射表腐化
- 清理 109 处与映射表一致的冗余硬编码(service 层)
- 保留业务特定消息覆盖能力

新增 API 用法:
- errors.New(errors.CodeUnauthorized) // 使用映射表默认消息
- errors.New(errors.CodeNotFound, "提现申请不存在") // 覆盖为自定义消息
2026-01-22 18:27:42 +08:00

92 lines
3.5 KiB
Markdown
Raw 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.
# error-code-validation Specification
## Purpose
TBD - created by archiving change unify-error-message-source. Update Purpose after archive.
## Requirements
### Requirement: 错误码消息映射完整性校验
系统 SHALL 在启动时校验所有已注册的错误码都有对应的 `errorMessages` 映射条目。
如果发现缺失映射,系统 MUST 立即 panic 并输出清晰的错误信息,指明缺失的错误码。
#### Scenario: 所有错误码都有映射时正常启动
- **WHEN** 所有 `allErrorCodes` 中的错误码都在 `errorMessages` 映射表中存在
- **THEN** 系统正常启动,无错误日志
#### Scenario: 存在缺失映射时启动失败
- **WHEN** 某个错误码(如 `CodeNewFeature = 1099`)在 `allErrorCodes` 中注册但 `errorMessages` 中缺失
- **THEN** 系统 panic错误信息包含 "错误码 1099 缺少映射消息"
### Requirement: 错误码注册表维护
系统 SHALL 维护一个 `allErrorCodes` 切片,包含所有已定义的错误码常量。
新增错误码时,开发者 MUST 同时:
1.`codes.go` 中定义常量
2.`allErrorCodes` 中注册
3.`errorMessages` 中添加映射
#### Scenario: 新增错误码完整注册
- **WHEN** 开发者新增错误码 `CodeXxx = 1100`
- **THEN** 必须同时在 `allErrorCodes``errorMessages` 中添加对应条目
- **THEN** 否则启动时 panic 或测试失败
### Requirement: errors.New 默认使用映射表消息
`errors.New()` 函数 SHALL 优先使用 `errorMessages` 映射表中的消息作为默认值。
当调用者提供自定义消息时,系统 MUST 允许覆盖默认消息。
#### Scenario: 不传消息参数时使用映射表
- **WHEN** 调用 `errors.New(errors.CodeNotFound)`
- **THEN** 返回的 `AppError.Message` 为 "资源未找到"(映射表中的值)
#### Scenario: 传空字符串时使用映射表
- **WHEN** 调用 `errors.New(errors.CodeNotFound, "")`
- **THEN** 返回的 `AppError.Message` 为 "资源未找到"(映射表中的值)
#### Scenario: 传自定义消息时覆盖映射表
- **WHEN** 调用 `errors.New(errors.CodeNotFound, "提现申请不存在")`
- **THEN** 返回的 `AppError.Message` 为 "提现申请不存在"(自定义值)
### Requirement: errors.Wrap 默认使用映射表消息
`errors.Wrap()` 函数 SHALL 与 `errors.New()` 保持一致的消息处理逻辑。
#### Scenario: Wrap 不传消息时使用映射表
- **WHEN** 调用 `errors.Wrap(errors.CodeDatabaseError, originalErr)`
- **THEN** 返回的 `AppError.Message` 为 "数据库错误"(映射表中的值)
- **THEN** 返回的 `AppError.Err``originalErr`
#### Scenario: Wrap 传自定义消息时覆盖
- **WHEN** 调用 `errors.Wrap(errors.CodeDatabaseError, "查询用户失败", originalErr)`
- **THEN** 返回的 `AppError.Message` 为 "查询用户失败"
- **THEN** 返回的 `AppError.Err``originalErr`
### Requirement: CI 测试覆盖映射完整性
系统 SHALL 提供单元测试 `TestAllCodesHaveMessages`,验证所有注册的错误码都有对应的映射。
此测试 MUST 在 CI 流程中运行,防止映射表腐化。
#### Scenario: 测试检测到缺失映射
- **WHEN** 运行 `go test ./pkg/errors/...`
- **WHEN** 存在错误码在 `allErrorCodes` 但不在 `errorMessages`
- **THEN** 测试失败,输出缺失的错误码列表
#### Scenario: 测试检测到孤立映射
- **WHEN** 运行 `go test ./pkg/errors/...`
- **WHEN** 存在映射条目的错误码不在 `allErrorCodes`
- **THEN** 测试失败,输出孤立的错误码列表(可选警告)