Mini Error Codes¶
从 CC 散落在多个文件的 28+ Error class(~1500 行)提炼到 ~150 行 的统一错误码注册表。 27 codes × 7 category + 4 helper(retry 判定 / category / status / 统计)。
文件¶
mini-error-codes/
├── src/
│ ├── errors.ts ERROR_CODES 注册表 + CodedError + 4 helper(~150 行)
│ └── cli.ts 5 测试场景
└── README.md
跑¶
真实代码对照¶
| Demo | 真实代码 | 简化 |
|---|---|---|
ERROR_CODES 字典 |
src/utils/errors.ts:200 28+ Error class |
27 合并到 1 张表 |
CodedError |
28 个独立 class | 1 个 class + codeName 字段 |
isRetryable |
src/utils/backoff.ts:30 |
检查 4 个 Node 系统错误码 |
format() |
src/utils/errors.ts:1200 |
含 code + status + user action |
27 Error Codes 分布¶
| Category | Count | Codes |
|---|---|---|
| network | 5 | TIMEOUT, OFFLINE, DNS, RESET, SSL |
| auth | 4 | INVALID_KEY, EXPIRED, INSUFFICIENT, MISSING |
| rate-limit | 3 | RATE_LIMIT, QUOTA_EXCEEDED, CONCURRENT_LIMIT |
| validation | 4 | INVALID_REQUEST, MISSING_FIELD, TOO_LARGE, UNSUPPORTED |
| internal | 4 | 500, 502, 503, 504 |
| tool | 3 | NOT_FOUND, TIMEOUT, FAILED |
| permission | 4 | TOOL_DENIED, BASH_DENIED, FILE_DENIED, NETWORK |
核心 4 件套¶
1️⃣ 集中注册表 vs 散落 class¶
// 真实 CC: 28 个 class(每个文件一个)
class NetworkTimeoutError extends Error { ... }
class AuthInvalidKeyError extends Error { ... }
// ... ×28
// Demo: 1 张表
const ERROR_CODES = {
ERR_NETWORK_TIMEOUT: { code, message, category, retryable, httpStatus, userAction },
// ...
};
cause 补救)。
2️⃣ CodedError = Error + meta¶
class CodedError extends Error {
constructor(public codeName: string, public cause?: unknown) {
const meta = ERROR_CODES[codeName];
super(meta?.message ?? codeName);
this.name = codeName;
}
get retryable() { return this.meta.retryable; }
format() { /* 输出 code + status + user action */ }
}
3️⃣ isRetryable 跨 Error 类型¶
function isRetryable(err: unknown): boolean {
if (err instanceof CodedError) return err.retryable;
if (err instanceof Error) {
const code = (err as any).code;
if (["ETIMEDOUT", "ECONNRESET", "ENOTFOUND", "ECONNREFUSED"].includes(code)) return true;
}
return false;
}
4️⃣ userAction = 给用户建议¶
每条 meta 都带 userAction 字段(如 "Run /login to set a new API key"),format() 时输出。真实场景:CC 终端报错时显示"如何修复",降低用户挫败感。
5 场景输出¶
📌 Test 1: list all 27 codes by category
📌 Test 2: format
❌ [ERR_NETWORK_TIMEOUT] Network request timed out (HTTP 408)
💡 Check your internet connection
📌 Test 3: isRetryable
CodedError 429 → retryable=true
CodedError 401 → retryable=false
Node ETIMEDOUT → retryable=true
普通 Error → retryable=false
📌 Test 4: simulate 10 errors
network:2 auth:1 rate-limit:3 validation:2 tool:1 permission:1
📌 Test 5: categoryOf + httpStatusOf
category=rate-limit httpStatus=429
category=tool httpStatus=n/a
进阶练习¶
- 加 i18n:message + userAction 支持多语言
- 加 telemetry:每次抛错上报 Sentry
- 加 cause chain:用 Error.cause 链式追踪
- 加 severity 分级:low(log)/ medium(warn)/ high(error)/ critical(alert)
- 加 doc link:每条 code 配 markdown 链接
- 加 auto-retry:retryable + 指数退避自动重试
相关阅读¶
- topics/error-codes.md —— 跨阶段专题
- analysis/error-handling.md —— 错误处理全景
- reference/error-classes.md —— 真实 28+ class 速查
- MDN Error.cause
- Node.js 系统错误码