@ranger1/dx 0.1.85 → 0.1.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -1
- package/codex/skills/e2e-audit-fixer/SKILL.md +76 -0
- package/codex/skills/e2e-audit-fixer/agents/openai.yaml +4 -0
- package/codex/skills/e2e-audit-fixer/scripts/e2e_e2e_audit.py +523 -0
- package/codex/skills/env-accessor-audit-fixer/SKILL.md +149 -0
- package/codex/skills/env-accessor-audit-fixer/agents/openai.yaml +7 -0
- package/codex/skills/env-accessor-audit-fixer/references/bootstrap-env-foundation.md +156 -0
- package/codex/skills/env-accessor-audit-fixer/scripts/env_accessor_audit.py +250 -0
- package/codex/skills/error-handling-audit-fixer/SKILL.md +150 -0
- package/codex/skills/error-handling-audit-fixer/agents/openai.yaml +7 -0
- package/codex/skills/error-handling-audit-fixer/references/error-handling-standard.md +152 -0
- package/codex/skills/error-handling-audit-fixer/references/foundation-bootstrap.md +85 -0
- package/codex/skills/error-handling-audit-fixer/scripts/error_handling_audit.py +537 -0
- package/codex/skills/pagination-dto-audit-fixer/SKILL.md +69 -0
- package/codex/skills/pagination-dto-audit-fixer/agents/openai.yaml +7 -0
- package/codex/skills/pagination-dto-audit-fixer/references/pagination-standard.md +67 -0
- package/codex/skills/pagination-dto-audit-fixer/scripts/pagination_dto_audit.py +244 -0
- package/lib/cli/commands/core.js +24 -8
- package/lib/cli/dx-cli.js +19 -9
- package/lib/cli/help.js +11 -6
- package/lib/codex-initial.js +155 -3
- package/lib/exec.js +21 -2
- package/lib/run-with-version-env.js +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: error-handling-audit-fixer
|
|
3
|
+
description: Use when backend、NestJS、领域异常治理或错误处理审查中,需要检查业务代码是否绕过 DomainException / ErrorCode 体系,区分生产代码与 E2E 测试中的异常写法,识别直接抛出 BadRequestException、HttpException、Error 或直接返回中文 DomainException,并在项目缺少统一异常基础设施时给出补齐路径。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 错误处理规范检查与修复建议
|
|
7
|
+
|
|
8
|
+
## 概览
|
|
9
|
+
|
|
10
|
+
先判断项目是否已经具备统一错误处理基础设施,再扫描业务代码是否绕过 `DomainException` / `ErrorCode` 体系。默认只输出审计结果和修复建议,不自动改代码;只有用户明确要求时才进入自动修复。
|
|
11
|
+
|
|
12
|
+
## 快速开始
|
|
13
|
+
|
|
14
|
+
1. 先审计生产代码:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
|
|
18
|
+
python "$CODEX_HOME/skills/error-handling-audit-fixer/scripts/error_handling_audit.py" \
|
|
19
|
+
--workspace "$PWD" \
|
|
20
|
+
--scope src
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. 再按需审计 E2E 或全量:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
python "$CODEX_HOME/skills/error-handling-audit-fixer/scripts/error_handling_audit.py" \
|
|
27
|
+
--workspace "$PWD" \
|
|
28
|
+
--scope all \
|
|
29
|
+
--output-json /tmp/error-handling-audit.json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
3. 当项目尚未具备 `DomainException` / `ErrorCode` / 领域异常目录等基础设施时,先阅读 [references/foundation-bootstrap.md](./references/foundation-bootstrap.md) 再决定是否补齐。
|
|
33
|
+
|
|
34
|
+
4. 当项目基础设施齐全但出现违规抛错时,按 [references/error-handling-standard.md](./references/error-handling-standard.md) 给出替换建议;如用户明确要求,才实施自动修复。
|
|
35
|
+
|
|
36
|
+
5. 当结果里 `e2e/raw-error` 数量很大时,不要直接把它和生产代码风险混在一起汇报;先给 `src` 结论,再决定是否单独治理 `e2e`。
|
|
37
|
+
|
|
38
|
+
## 执行流程
|
|
39
|
+
|
|
40
|
+
1. 默认先扫描 `apps/backend/src`,只有在用户明确要求或需要评估测试债务时再扫描 `apps/backend/e2e`。
|
|
41
|
+
2. 先判断基础设施状态:
|
|
42
|
+
- 是否存在 `DomainException`
|
|
43
|
+
- 是否存在 `ErrorCode`
|
|
44
|
+
- 是否存在领域异常目录或模块异常类
|
|
45
|
+
- 是否存在全局异常过滤器或结构化错误输出链路
|
|
46
|
+
3. 再识别四类问题:
|
|
47
|
+
- 直接实例化 Nest 标准异常,如 `BadRequestException`、`HttpException`
|
|
48
|
+
- `throw new Error(...)` 或 `Promise.reject(new Error(...))`
|
|
49
|
+
- 直接 `new DomainException(...)` 但 payload 中未显式带 `code`
|
|
50
|
+
- `DomainException` 直接返回中文 message
|
|
51
|
+
4. 对每个命中项给出修复建议,优先级固定如下:
|
|
52
|
+
- 优先复用现有模块异常类
|
|
53
|
+
- 其次建议在模块 `exceptions/` 目录新增领域异常类
|
|
54
|
+
- 最后才允许直接使用 `DomainException`,且必须补齐 `code` 与 `args`
|
|
55
|
+
5. 若基础设施缺失,不直接把全部命中项定性为“应立刻改业务代码”,而是先输出“需补齐基础设施”的诊断与最小落地路径。
|
|
56
|
+
6. 只有在用户明确说“自动修复”“直接改”或等价表述时,才进入落代码阶段。
|
|
57
|
+
7. 若脚本结果与实际代码不一致,必须抽样打开命中文件复核,不要把脚本结果当成绝对真相。
|
|
58
|
+
|
|
59
|
+
## 审计命令
|
|
60
|
+
|
|
61
|
+
项目具备 ripgrep 时,可先用下列命令快速复核:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
rg "new (BadRequestException|UnauthorizedException|ForbiddenException|NotFoundException|HttpException|InternalServerErrorException)\(" \
|
|
65
|
+
apps/backend/src apps/backend/e2e \
|
|
66
|
+
--glob '!*spec.ts' \
|
|
67
|
+
--glob '!*exception.ts' \
|
|
68
|
+
--glob '!apps/backend/src/common/filters/**' \
|
|
69
|
+
--glob '!apps/backend/src/main.ts'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
rg "new Error\(" apps/backend/src apps/backend/e2e --glob '!*spec.ts'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
rg "new DomainException\([^)]*$" -A3 apps/backend/src
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
rg "DomainException\([^)]*[\u4e00-\u9fa5]" apps/backend/src apps/backend/e2e \
|
|
82
|
+
--glob '!*spec.ts' \
|
|
83
|
+
--glob '!apps/backend/src/common/exceptions/**'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
如果只想快速看生产代码,可优先改成:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python "$CODEX_HOME/skills/error-handling-audit-fixer/scripts/error_handling_audit.py" \
|
|
90
|
+
--workspace "$PWD" \
|
|
91
|
+
--scope src
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
如果只想看 E2E 存量问题,可改成:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
python "$CODEX_HOME/skills/error-handling-audit-fixer/scripts/error_handling_audit.py" \
|
|
98
|
+
--workspace "$PWD" \
|
|
99
|
+
--scope e2e
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 修复准则
|
|
103
|
+
|
|
104
|
+
### 1. 优先复用现有领域异常
|
|
105
|
+
|
|
106
|
+
- 若模块 `exceptions/` 已有语义匹配的异常类,直接复用。
|
|
107
|
+
- 不要把已可表达为领域异常的问题继续保留成裸 `BadRequestException('字符串')`。
|
|
108
|
+
|
|
109
|
+
### 2. 缺少模块异常时新增领域异常类
|
|
110
|
+
|
|
111
|
+
- 在模块 `exceptions/` 下新增异常类。
|
|
112
|
+
- 异常类继承统一 `DomainException`。
|
|
113
|
+
- 构造函数中显式指定 `ErrorCode`。
|
|
114
|
+
- 把上下文放进 `args`,不要把业务文案直接写死到 message。
|
|
115
|
+
- 为新增异常补最小单测。
|
|
116
|
+
|
|
117
|
+
### 3. 临时直接使用 DomainException
|
|
118
|
+
|
|
119
|
+
- 仅在尚未抽出专用异常类、但当前修复必须继续推进时使用。
|
|
120
|
+
- payload 中必须显式包含 `code`。
|
|
121
|
+
- `args` 中必须保留排障所需上下文。
|
|
122
|
+
|
|
123
|
+
### 4. 基础设施缺失时的判断
|
|
124
|
+
|
|
125
|
+
- 如果仓库里根本没有 `DomainException` 或 `ErrorCode`,优先建议补基础设施,不要直接发散式新增几十个本地异常实现。
|
|
126
|
+
- 如果已有 `DomainException` 但没有统一 `ErrorCode`,先统一错误码来源,再扩展模块异常。
|
|
127
|
+
- 如果已有异常类与错误码,但缺少结构化输出链路,优先补过滤器或输出映射,保证 `code`、`args`、`requestId` 可稳定透出。
|
|
128
|
+
|
|
129
|
+
## 输出要求
|
|
130
|
+
|
|
131
|
+
执行这个技能时,最终输出至少包含:
|
|
132
|
+
|
|
133
|
+
1. 基础设施状态
|
|
134
|
+
2. 命中文件清单
|
|
135
|
+
3. 每个问题的类型、定位与建议替换方式
|
|
136
|
+
4. 是否可复用现有领域异常
|
|
137
|
+
5. 是否需要先补齐基础设施
|
|
138
|
+
6. 若用户要求自动修复,列出拟修改文件、验证方式与剩余风险
|
|
139
|
+
|
|
140
|
+
补充要求:
|
|
141
|
+
|
|
142
|
+
7. 明确区分 `src` 与 `e2e` 命中数量,避免测试噪音淹没生产代码风险
|
|
143
|
+
8. 标注哪些命中是脚本结果、哪些已经过源码抽样复核
|
|
144
|
+
9. 若脚本疑似误报,要在结论里明确说明“脚本规则限制”而不是直接要求改代码
|
|
145
|
+
|
|
146
|
+
## 资源
|
|
147
|
+
|
|
148
|
+
- 扫描脚本:`scripts/error_handling_audit.py`
|
|
149
|
+
- 规范参考:`references/error-handling-standard.md`
|
|
150
|
+
- 基础设施补齐指南:`references/foundation-bootstrap.md`
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "错误处理规范检查"
|
|
3
|
+
short_description: "按 src 与 e2e 分开审计后端异常是否绕过 DomainException 与 ErrorCode 体系"
|
|
4
|
+
default_prompt: "使用 $error-handling-audit-fixer 先审计 backend src,再按需审计 e2e,检查错误处理是否绕过 DomainException / ErrorCode 体系,并在基础设施缺失时给出补齐建议。"
|
|
5
|
+
|
|
6
|
+
policy:
|
|
7
|
+
allow_implicit_invocation: true
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# 错误处理规范参考
|
|
2
|
+
|
|
3
|
+
## 目标
|
|
4
|
+
|
|
5
|
+
后端业务代码抛出异常时,应统一接入 `DomainException` / `ErrorCode` 体系,避免直接抛出字符串化的 Nest 标准异常或裸 `Error`,以保证:
|
|
6
|
+
|
|
7
|
+
- 前端可稳定依赖 `error.code`
|
|
8
|
+
- 日志具备结构化 `args`
|
|
9
|
+
- 请求链路可透出 `requestId`
|
|
10
|
+
- 模块内异常语义可复用
|
|
11
|
+
|
|
12
|
+
## 默认排除范围
|
|
13
|
+
|
|
14
|
+
- `apps/backend/src/common/exceptions/**/*.ts`
|
|
15
|
+
- `apps/backend/src/common/filters/**/*.ts`
|
|
16
|
+
- `apps/backend/src/main.ts`
|
|
17
|
+
- `*.spec.ts`
|
|
18
|
+
|
|
19
|
+
说明:
|
|
20
|
+
|
|
21
|
+
- 领域异常定义文件允许继承和封装 Nest 异常能力
|
|
22
|
+
- 全局过滤器允许直接接触 Nest 异常
|
|
23
|
+
- `main.ts` 中的 `ValidationPipe` 自定义异常通常属于框架接线层
|
|
24
|
+
|
|
25
|
+
## 检测规则
|
|
26
|
+
|
|
27
|
+
### 1. 直接实例化 Nest 标准异常
|
|
28
|
+
|
|
29
|
+
命中对象:
|
|
30
|
+
|
|
31
|
+
- `BadRequestException`
|
|
32
|
+
- `UnauthorizedException`
|
|
33
|
+
- `ForbiddenException`
|
|
34
|
+
- `NotFoundException`
|
|
35
|
+
- `HttpException`
|
|
36
|
+
- `InternalServerErrorException`
|
|
37
|
+
|
|
38
|
+
通常表示业务语义绕过了领域异常体系。
|
|
39
|
+
|
|
40
|
+
### 2. 直接创建 Error
|
|
41
|
+
|
|
42
|
+
命中对象:
|
|
43
|
+
|
|
44
|
+
- `throw new Error(...)`
|
|
45
|
+
- `Promise.reject(new Error(...))`
|
|
46
|
+
|
|
47
|
+
这类写法通常无法提供稳定错误码,也不利于结构化日志。
|
|
48
|
+
|
|
49
|
+
### 3. DomainException 缺少 code
|
|
50
|
+
|
|
51
|
+
命中对象:
|
|
52
|
+
|
|
53
|
+
- `new DomainException(...)` 但 payload 未显式声明 `code`
|
|
54
|
+
|
|
55
|
+
即使暂时不抽专用异常类,也必须提供 `ErrorCode`。
|
|
56
|
+
|
|
57
|
+
### 4. DomainException 直接返回中文 message
|
|
58
|
+
|
|
59
|
+
命中对象:
|
|
60
|
+
|
|
61
|
+
- `DomainException(...)` 中直接出现中文 message
|
|
62
|
+
|
|
63
|
+
后端不应直接决定面向用户的中文文案。优先返回稳定错误码,由前端或上层映射展示。
|
|
64
|
+
|
|
65
|
+
## 修复优先级
|
|
66
|
+
|
|
67
|
+
1. 复用现有模块异常类
|
|
68
|
+
2. 新增模块领域异常类
|
|
69
|
+
3. 临时直接使用 `DomainException`
|
|
70
|
+
|
|
71
|
+
## 正反例
|
|
72
|
+
|
|
73
|
+
### 错误示例
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
throw new BadRequestException('余额不足, 请充值')
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
throw new Error('wallet not found')
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
throw new DomainException('余额不足')
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 正确示例:复用模块异常
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
throw new InsufficientBalanceException({
|
|
91
|
+
currentBalance: wallet.available,
|
|
92
|
+
requestedAmount: dto.amount,
|
|
93
|
+
isFromFreeze: false,
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 正确示例:临时直接使用 DomainException
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
throw new DomainException('wallet.insufficient_balance', {
|
|
101
|
+
code: ErrorCode.WALLET_INSUFFICIENT_BALANCE,
|
|
102
|
+
args: {
|
|
103
|
+
currentBalance: wallet.available,
|
|
104
|
+
requestedAmount: dto.amount,
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 建议替换策略
|
|
110
|
+
|
|
111
|
+
### BadRequestException
|
|
112
|
+
|
|
113
|
+
- 参数校验类错误:优先看是否属于框架输入校验层
|
|
114
|
+
- 业务校验类错误:优先替换为模块领域异常
|
|
115
|
+
|
|
116
|
+
### NotFoundException
|
|
117
|
+
|
|
118
|
+
- 若资源查找失败属于明确业务语义,替换为 `XxxNotFoundException`
|
|
119
|
+
|
|
120
|
+
### ForbiddenException / UnauthorizedException
|
|
121
|
+
|
|
122
|
+
- 若表达的是业务权限或业务身份限制,替换为模块异常
|
|
123
|
+
- 若是认证框架本身的接入层,可保留在边界层
|
|
124
|
+
|
|
125
|
+
### HttpException
|
|
126
|
+
|
|
127
|
+
- 一般视为待治理项,优先改成领域异常或统一异常封装
|
|
128
|
+
|
|
129
|
+
### Error
|
|
130
|
+
|
|
131
|
+
- 原则上应全部迁移到领域异常或基础设施异常
|
|
132
|
+
|
|
133
|
+
## 输出建议模板
|
|
134
|
+
|
|
135
|
+
每个命中项建议包含:
|
|
136
|
+
|
|
137
|
+
- 文件路径
|
|
138
|
+
- 行号
|
|
139
|
+
- 问题类型
|
|
140
|
+
- 当前写法
|
|
141
|
+
- 推荐替换方式
|
|
142
|
+
- 是否可复用已有异常类
|
|
143
|
+
- 若不可复用,建议新增的异常类名
|
|
144
|
+
|
|
145
|
+
## 何时不要直接修
|
|
146
|
+
|
|
147
|
+
- 仓库尚未定义 `DomainException`
|
|
148
|
+
- 仓库没有统一 `ErrorCode`
|
|
149
|
+
- 现有全局过滤器不会透出 `code` / `args` / `requestId`
|
|
150
|
+
- 当前模块不存在异常目录,且团队尚未确认命名规范
|
|
151
|
+
|
|
152
|
+
遇到以上情况,先转向基础设施补齐。
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# 错误处理基础设施补齐指南
|
|
2
|
+
|
|
3
|
+
## 适用场景
|
|
4
|
+
|
|
5
|
+
当项目执行错误处理规范审计时,若发现缺少以下任一基础设施,应先补齐,再推进大规模业务修复:
|
|
6
|
+
|
|
7
|
+
- `DomainException`
|
|
8
|
+
- `ErrorCode`
|
|
9
|
+
- 领域异常目录约定
|
|
10
|
+
- 全局异常过滤器或统一错误输出链路
|
|
11
|
+
|
|
12
|
+
## 最小可用基础设施
|
|
13
|
+
|
|
14
|
+
### 1. DomainException
|
|
15
|
+
|
|
16
|
+
需要具备:
|
|
17
|
+
|
|
18
|
+
- 统一异常基类
|
|
19
|
+
- 接收稳定 `messageKey` 或内部 message
|
|
20
|
+
- payload 至少支持:
|
|
21
|
+
- `code`
|
|
22
|
+
- `args`
|
|
23
|
+
- `cause`
|
|
24
|
+
- 可扩展的 `meta`
|
|
25
|
+
|
|
26
|
+
### 2. ErrorCode
|
|
27
|
+
|
|
28
|
+
需要具备:
|
|
29
|
+
|
|
30
|
+
- 集中定义的枚举或常量集
|
|
31
|
+
- 可按模块分组命名
|
|
32
|
+
- 命名稳定,不直接耦合中文文案
|
|
33
|
+
|
|
34
|
+
示例命名:
|
|
35
|
+
|
|
36
|
+
- `WALLET_INSUFFICIENT_BALANCE`
|
|
37
|
+
- `USER_NOT_FOUND`
|
|
38
|
+
- `AUTH_LOGIN_EXPIRED`
|
|
39
|
+
|
|
40
|
+
### 3. 模块异常目录
|
|
41
|
+
|
|
42
|
+
推荐:
|
|
43
|
+
|
|
44
|
+
- 每个业务模块使用 `exceptions/` 目录
|
|
45
|
+
- 每个异常类表达单一明确业务语义
|
|
46
|
+
- 不在 Service 里散落大量 `new DomainException(...)`
|
|
47
|
+
|
|
48
|
+
### 4. 全局异常过滤器
|
|
49
|
+
|
|
50
|
+
输出应至少包含:
|
|
51
|
+
|
|
52
|
+
- `code`
|
|
53
|
+
- `message`
|
|
54
|
+
- `args`
|
|
55
|
+
- `requestId`
|
|
56
|
+
- `timestamp`
|
|
57
|
+
- `path`
|
|
58
|
+
|
|
59
|
+
如果现有过滤器只输出字符串 message,需要先升级输出结构。
|
|
60
|
+
|
|
61
|
+
## 推荐补齐顺序
|
|
62
|
+
|
|
63
|
+
1. 建立 `ErrorCode`
|
|
64
|
+
2. 建立 `DomainException`
|
|
65
|
+
3. 建立全局异常过滤器输出契约
|
|
66
|
+
4. 在一个模块内先试点 1 到 2 个领域异常类
|
|
67
|
+
5. 再批量治理业务代码中的裸异常
|
|
68
|
+
|
|
69
|
+
## 迁移原则
|
|
70
|
+
|
|
71
|
+
- 先收敛契约,再批量替换调用点
|
|
72
|
+
- 先在高频模块试点,再扩散到全仓
|
|
73
|
+
- 保持旧错误响应的兼容窗口,避免前端瞬间失配
|
|
74
|
+
- 中文文案不要直接塞进后端异常 message,优先使用 code + args
|
|
75
|
+
|
|
76
|
+
## 自动修复前的门槛
|
|
77
|
+
|
|
78
|
+
只有在以下条件满足时,才适合让 AI 直接批量修代码:
|
|
79
|
+
|
|
80
|
+
- `DomainException` 已可复用
|
|
81
|
+
- `ErrorCode` 已有统一来源
|
|
82
|
+
- 全局过滤器已能稳定透出结构化字段
|
|
83
|
+
- 模块异常类命名规则已经明确
|
|
84
|
+
|
|
85
|
+
否则默认只给建议,不默认改业务代码。
|