关于 handling-failures
一项规定代码如何报告和处理故障、避免掩盖错误的软件工程技能,面向工程 Agent,要求具备 `principal-engineering` 技能。
主要功能
- 01记录日志并重新抛出故障
- 02返回调用方必须处理的类型化故障
- 03记录并显式呈现降级模式
- 04限制重试并保持可观测
- 05确保副作用操作可幂等重放
适用场景
- 01审查代码中的异常处理
- 02设计可观测的故障路径
- 03检查降级行为与重试机制
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ riekelt/ principal-engineer --skill handling-failures安装后在 Claude Code 中输入/handling-failures确认已加载。
详细介绍
处理失败
必备背景:principal-engineering 技能。
概述
被吞掉的错误,就是证据被销毁的 Bug。核心约定:每条失败路径都必须且只需执行以下三种操作之一,而且这三种操作都必须引人注意。 系统表面上运行正常却提供错误数据,比直接崩溃更糟。
约定
每个 catch 和失败路径都必须执行以下操作之一:
- 以 WARN 或 ERROR 级别记录日志并重新抛出,或
- 记录日志并返回调用方必须处理的类型化失败(例如结果类型、封闭错误类型,或编译器或契约强制下游代码处理的状态),或
- 记录日志并进入有明确文档说明的降级模式(在代码和文档中为该模式命名,并提供可观测信号表明系统处于降级状态)。
以下行为一律禁止,不得例外:
- 仅捕获错误并继续执行。
- 捕获错误后返回默认值(空列表、null、零、缓存副本)来掩盖失败。
- 使用
?? fallback及类似写法,让回退值掩盖主要操作的失败。只有在其他地方也明确暴露缺失情况时,才可以使用回退值。
推论
- 缺少必需条目时必须明确失败。 注册表、配置或目录中缺少条目,必须导致构建或启动失败,绝不能静默使用默认值。
- 错误状态必须可见。 工作流失败时不能看起来仍在正常运行;应在 UI、指标或有人实际查看的日志中显示错误状态。
- 面向运维人员的补救措施必须具体。“连接失败,请检查 REDIS_URL 以及 redis 是否能响应 PING”胜过“发生错误”。
- 重试必须有上限且可观测。
- 副作用操作的重放必须具备幂等性。
- 降级模式必须有界限。 跳过并继续执行时,必须明确规定降级何时转为中止,并将阈值设为具名、可由运维人员调整的常量。必须存在相应的保护措施;阈值取值应与负责人共同商定。无界降级模式就是缓慢发生的错误吞噬。
- 在失败路径中,可观测性是最低要求的一部分,不是锦上添花。修复必须同时包含日志、计数器和告警;缺少这些内容的失败路径,只是打着更好意图旗号的静默错误吞噬。
处理现有的错误吞噬
如果你正在编辑的代码已经会吞掉错误:应将其一并修复,或明确指出它仍待处理以及它会掩盖什么。默默放任就是认可这种做法。在代码审查中,新出现的静默错误吞噬一律视为阻止合并的问题;已存在且你修改过但未标明的问题,则会作为警告指出此次改动。
常见错误
- 以“这种情况绝不会发生”为由吞掉错误。恰恰是这些路径发生问题时,最需要明确的警报。
- 以 DEBUG 级别记录日志就认为问题已处理。如果生产环境中没人能看到它,这不过是多绕了一步的错误吞噬。
- 为处理狭窄情况而捕获宽泛错误(
Exception、catch {})。意外失败会悄无声息地与预期失败一同消失。 - 降级模式没有文档说明。只有作者知道的降级,对运维人员而言就是无法诊断的服务中断。
- 通过为失败设置默认值来让测试通过。测试变绿了,缺陷却进入了生产环境。
评论
支持 Markdown