feat(error): 业务错误码注册表(子模块 + openspec change + guide)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ed9af5337d
commit
062b314844
@ -473,7 +473,7 @@ useDict(code) // → { items, tagMap, options },均响应式
|
||||
{ "code": 0, "message": "ok", "data": { } }
|
||||
```
|
||||
|
||||
- `code=0` 成功;失败 `code = HTTP状态码 * 100`(401→40100,403→40300,400→40000,500→50000)。
|
||||
- `code=0` 成功;失败 `code` 为业务码(5 位 `[域码 2 位][序 3 位]`,单一注册表见 [`src/common/error-codes.ts`](../sources/sysmgr-nest/src/common/error-codes.ts),如 `10001` 账号或密码错误、`11002` 用户名已存在);未登记业务码的异常回退 `HTTP状态码 × 100`(40000/40100/40300/40400/40900/50000)。
|
||||
- 前端 `http` 已自动拆包:成功拿 `data`,失败抛 `ApiError(code, message)`。
|
||||
|
||||
### 4.2 分页
|
||||
|
||||
2
openspec/changes/error-code-registry/.openspec.yaml
Normal file
2
openspec/changes/error-code-registry/.openspec.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-10-11
|
||||
40
openspec/changes/error-code-registry/design.md
Normal file
40
openspec/changes/error-code-registry/design.md
Normal file
@ -0,0 +1,40 @@
|
||||
## Context
|
||||
|
||||
`AllExceptionsFilter` 目前把 `HttpException` 统一映射为 `code = HTTP 状态 ×100`;业务 throw 都是 `BadRequestException/ConflictException/NotFoundException('字符串')`,无 code。前端 `ApiError(code, message)` 已读 code,但无稳定业务码可分支。动机见 proposal.md - Why。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- 建立单一错误码注册表与 `BusinessException`,迁移关键业务错误。
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- 不一次性迁移全部 throw(逐步);不引入错误码国际化/多语言。
|
||||
|
||||
## Decisions
|
||||
|
||||
### D1 — code 方案:`[域码 2 位][序 3 位]`
|
||||
5 位数字。域码固定:00 通用、10 认证、11 用户、12 角色、13 资源、14 组织、15 租户、16 字典、17 配置、18 审计、19 登录、20 会话、21 通知。HTTP 状态由 `BusinessException` 单独携带,`code` 与 HTTP 解耦。
|
||||
|
||||
### D2 — `BusinessException` + 过滤器识别
|
||||
`src/common/business-exception.ts`:`class BusinessException extends HttpException { constructor(code, message, status = 400) }`。`AllExceptionsFilter`:若为 `BusinessException` 用其 `code`,否则回退 `status×100`。
|
||||
|
||||
### D3 — 注册表为单一事实源
|
||||
`src/common/error-codes.ts` 集中登记:通用码 + 各域码,注释标明 HTTP 状态。新增业务错误先在注册表加码,再 `throw new BusinessException(ErrorCodes.XXX, '...')`。
|
||||
|
||||
### D4 — 迁移关键错误(示例集)
|
||||
迁移:登录(账号或密码错误/锁定/停用)、待改密门禁、用户名冲突、原密码错误、用户/租户/资源不存在、越权等高频错误;其余保留字符串(可后续迁移)。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- **[code 与 HTTP 解耦后前端需注意]** → 前端 `ApiError.code` 现为业务码;HTTP 状态仍用于 401 自动刷新(http.ts 按 status 判断,不受影响)。
|
||||
- **[迁移不完整]** → 未迁移的仍回退 `status×100`,与注册码并存,逐步收敛。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
无数据迁移;纯后端代码 + 文档。回滚即撤销。
|
||||
|
||||
## Open Questions
|
||||
|
||||
无。
|
||||
21
openspec/changes/error-code-registry/proposal.md
Normal file
21
openspec/changes/error-code-registry/proposal.md
Normal file
@ -0,0 +1,21 @@
|
||||
## Why
|
||||
|
||||
当前业务错误都是字符串消息(`throw new BadRequestException('用户名已存在')`),无统一错误码,前端无法按 code 分支处理,fork 后各模块各自为政。需要一套「业务域 + 错误序」的错误码注册表作为单一事实源。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 新增 `src/common/error-codes.ts` 错误码注册表(5 位数字 `[域码 2 位][序 3 位]`,域码集中登记)。
|
||||
- 新增 `BusinessException(code, message, status)`;`AllExceptionsFilter` 识别业务码,非业务异常仍回退 `HTTP×100`。
|
||||
- 迁移关键业务错误(登录/锁定/待改密/用户名冲突/租户不存在等)到注册码。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `shared/api-contract`: 「错误码分段」改为「业务域 + 错误序」细分段。
|
||||
|
||||
## Impact
|
||||
|
||||
- **后端**:`error-codes.ts` + `business-exception.ts`(common)、`AllExceptionsFilter` 识别业务码、auth/users/tenants 等关键 throw 迁移。
|
||||
- **文档**:guide.md 补错误码注册表说明。
|
||||
- 无数据/前端变更(前端仍读 `code` + `message`)。
|
||||
@ -0,0 +1,16 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 错误码分段
|
||||
错误码 SHALL 采用「业务域 + 错误序」分段:5 位数字 `[域码 2 位][序 3 位]`,域码集中登记于 `error-codes` 注册表(00 通用、10 认证、11 用户、12 角色、13 资源、14 组织、15 租户、16 字典、17 配置、20 会话、21 通知…);HTTP 状态仍按语义返回(400/401/403/404/409/500),`code` 为业务码。
|
||||
|
||||
#### Scenario: 未登录
|
||||
- **WHEN** 未携带有效 token 访问受保护接口
|
||||
- **THEN** HTTP 401,code 为认证域业务码(如 10002),无业务码时回退 40100
|
||||
|
||||
#### Scenario: 业务错误码
|
||||
- **WHEN** 业务处理失败(如用户名已存在)
|
||||
- **THEN** 返回对应 HTTP 状态 + 注册表内的业务码与可读 message
|
||||
|
||||
#### Scenario: 系统错误兜底
|
||||
- **WHEN** 非业务异常(框架/未知错误)
|
||||
- **THEN** code 回退为 HTTP 状态 ×100
|
||||
18
openspec/changes/error-code-registry/tasks.md
Normal file
18
openspec/changes/error-code-registry/tasks.md
Normal file
@ -0,0 +1,18 @@
|
||||
## 1. 基础设施
|
||||
|
||||
- [x] 1.1 新增 `src/common/error-codes.ts`(域码 + 通用码 + 各域码集中登记)
|
||||
- [x] 1.2 新增 `src/common/business-exception.ts`(`BusinessException(code, message, status)`)
|
||||
- [x] 1.3 `AllExceptionsFilter` 识别 `BusinessException`,否则回退 `status×100`
|
||||
|
||||
## 2. 迁移关键错误
|
||||
|
||||
- [x] 2.1 `auth.service`:登录失败/锁定/停用/待改密/原密码错误
|
||||
- [x] 2.2 `users.service`:用户名冲突、用户不存在
|
||||
- [x] 2.3 `tenants.service`:租户不存在/已存在
|
||||
- [x] 2.4 `sessions.service`:会话不存在
|
||||
|
||||
## 3. 文档与验证
|
||||
|
||||
- [x] 3.1 guide.md 补错误码注册表说明
|
||||
- [x] 3.2 后端 build + 单测 + e2e 通过
|
||||
- [x] 3.3 冒烟:触发一个业务错误,返回注册业务码而非 status×100
|
||||
@ -1 +1 @@
|
||||
Subproject commit f747ad5442e314f41d9319b61941da5f7af69096
|
||||
Subproject commit 8eefa7fa4499ed9b3c733211794360fad26061b4
|
||||
Loading…
x
Reference in New Issue
Block a user