错误处理 handling-errors

错误处理技能专注于在编程中有效管理错误,包括设计错误处理策略、避免静默失败、保留错误上下文,以及优雅地处理不同类型的错误。适用于软件开发中的各种场景,提升代码质量和用户体验。关键词:错误处理、异常处理、编程、软件架构、错误日志、Result模式。

架构设计 0 次安装 0 次浏览 更新于 3/5/2026

name: handling-errors description: 防止错误处理中的静默失败和上下文丢失。在编写try-catch块、设计错误传播、审查catch块或实现Result模式时使用。

错误处理

铁律

  1. 永不吞没错误 - 空的catch块隐藏bug
  2. 永不将错误转换为布尔值 - 丢失所有上下文
  3. 保留错误上下文 当包装或传播时
  4. 在处理的层记录一次,而不是每一层

错误消息

每个错误消息回答:发生了什么?为什么?如何恢复?

对于日志(开发者):

logger.error("保存用户失败:30秒后连接超时", {
  userId: user.id,
  dbHost: config.db.host,
  error: error.stack,
});

对于用户:

对于面向用户的错误文案,使用 Skill(ce:writer)UX Writer 角色。关键原则:

  • 简洁具体(不是“出了点问题”)
  • 可操作(告诉他们下一步做什么)
  • 不责备(永远不要说“您输入无效…”)
showError({
  title: "上传失败",
  message: "文件超过10MB限制。选择一个更小的文件。",
  actions: [{ label: "选择文件", onClick: selectFile }],
});

错误类别

类型 示例 处理方式
预期 验证错误、未找到、未授权 返回Result类型,记录信息日志
瞬态 网络超时、速率限制 重试并退避,记录警告日志
意外 空引用、数据库崩溃 记录错误日志,显示支持ID
关键 认证服务宕机、支付网关离线 断路器,警报

快速失败与优雅降级

快速失败 对于关键依赖:

await connectToDatabase(); // 失败时抛出异常 - 应用无法在没有它的情况下运行

优雅降级 对于可选功能:

const prefs = await loadPreferences(userId).catch(() => DEFAULT_PREFS);

在正确的层记录日志

// ❌ 在每一层记录日志 = 相同错误记录3次
async function fetchData() {
  try { return await fetch(url); }
  catch (e) { console.error("获取数据失败:", e); throw e; }
}

// ✅ 在处理的地方记录一次
async function fetchData() {
  const response = await fetch(url);
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response;
}
// 顶层记录错误一次

语言特定模式

反模式

模式 问题 修复
空的catch块 隐藏错误 记录或重新抛出
return false 错误时 丢失上下文 返回Result类型
通用的“错误”消息 难以调试 包含内容/原因/上下文
在每一层记录相同错误 日志污染 在边界记录一次
except: / catch (e) 所有 捕获系统信号 捕获特定类型