mcpField
E
error-handling

error-handling

github.com/metarhia开发6038 次安装12 周前更新
代码仓库

关于 error-handling

面向开发者的错误处理技能,提供 JavaScript 同步、异步及跨层错误处理约定,涵盖恢复、传播与进程退出。

主要功能

  1. 01区分编程错误与运行时错误
  2. 02处理同步和异步异常
  3. 03使用 DomainError 表达业务错误
  4. 04配置重试与进程级处理器
  5. 05支持优雅关闭

适用场景

  1. 01为 API 业务错误映射结构化代码
  2. 02为临时网络故障添加重试
  3. 03排查未捕获异常和未处理拒绝

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/metarhia/metaskills --skill error-handling

安装后在 Claude Code 中输入/error-handling确认已加载。

详细介绍

错误处理

错误分类

  • 编程错误:缺陷(TypeError、ReferenceError、断言失败等)。修复代码;不要捕获后继续执行
  • 运行时错误:预期会发生的失败(网络超时、文件未找到、输入无效等)。通过恢复、升级处理、通知用户或记录日志来妥善处理

同步错误处理

try {
  const result = parse(input);
  return result;
} catch (error) {
  console.error({ error });
  return defaultValue;
}

异步错误处理

try {
  const data = await fetchData(url);
  return data;
} catch (error) {
  if (error.code === 'ECONNREFUSED') return fallback();
  throw err;
}

DomainError

面向 API 层、包含错误代码的结构化业务错误:

({
  method: async ({ email }) => {
    const user = await domain.user.findByEmail(email);
    if (!user) return new DomainError('ENOTFOUND');
    return user;
  },
  errors: { ENOTFOUND: 'User not found' },
});

领域层抛出普通错误;必要时由 API 层将其转换为 DomainError。

跨层错误传播

domain throws Error → API catches → returns DomainError(code) → client gets structured error

不要向客户端暴露内部错误详情;将错误映射为已知错误代码或通用错误。

约定

  • 区分编程错误和运行时错误;只对运行时错误进行恢复
  • 在 API 方法中使用 DomainError 处理业务验证;编程缺陷应抛出错误
  • 绝不静默吞掉错误;始终记录日志或向上传播
  • 实现平稳关闭:停止接受连接,处理完现有连接并释放资源
  • 对临时故障(网络、数据库连接)使用指数退避重试
  • 始终在进程级别处理 uncaughtException 和 unhandledRejection

重试模式

const retry = async (fn, { attempts = 3, delay = 1000 } = {}) => {
  for (let i = 0; i < attempts; i++) {
    try {
      return await fn();
    } catch (err) {
      if (i === attempts - 1) throw err;
      await new Promise((r) => setTimeout(r, delay * (i + 1)));
    }
  }
};

进程级处理程序

process.on('uncaughtException', (error) => {
  console.error('Uncaught:', error);
  process.exit(1);
});

process.on('unhandledRejection', (reason) => {
  console.error('Unhandled rejection:', reason);
});

对于 uncaughtException,记录日志并退出(状态可能已损坏)。对于 unhandledRejection,记录日志并将其视为需要修复的缺陷。

平稳关闭

跟踪连接,并在退出前处理完所有连接:

const connections = new Map();

server.on('connection', (conn) => {
  const res = null;
  connections.set(conn, res);
  conn.on('close', () => connections.delete(conn));
});

const shutdown = () => {
  server.close(() => {
    freeResources();
    process.exit(0);
  });
  for (const [conn, res] of connections) {
    if (res) res.end('Server shutting down');
    conn.destroy();
  }
};

process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);

评论

支持 Markdown