跳转至

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

npm install && npm start

真实代码对照

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 },
  // ...
};
优势:新增/修改错误码只改一处劣势:丢失 stack trace 精度(用 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 */ }
}
统一 stack + 统一 format + 统一 retry 判定

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;
}
兼容 CodedError + Node 系统错误(最常见的 4 个网络错误码)。

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

进阶练习

  1. 加 i18n:message + userAction 支持多语言
  2. 加 telemetry:每次抛错上报 Sentry
  3. 加 cause chain:用 Error.cause 链式追踪
  4. 加 severity 分级:low(log)/ medium(warn)/ high(error)/ critical(alert)
  5. 加 doc link:每条 code 配 markdown 链接
  6. 加 auto-retry:retryable + 指数退避自动重试

相关阅读