关于 codeprobe-error-handling
用于检查软件错误处理与韧性的 codeprobe 技能,审查异常处理、输入验证、外部调用、事务安全、错误响应和日志。
主要功能
- 01查找被吞掉或范围过宽的异常
- 02检查外部调用的错误处理
- 03审查验证逻辑与空值假设
- 04检查重试、超时和事务安全
- 05审查错误响应与故障日志
适用场景
- 01审计代码库中的异常处理
- 02检查外部调用是否设置超时和重试
- 03审查验证逻辑与数据库事务路径
- 04查找故障日志和错误响应的缺口
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ machineroom-dev/ codeprobe --skill codeprobe-error-handling安装后在 Claude Code 中输入/codeprobe-error-handling确认已加载。
详细介绍
独立模式
如果直接调用(而非通过协调器调用),必须先:
- 读取
../codeprobe/shared-preamble.md(相对于此 SKILL.md 所在位置解析,即同级的codeprobe技能目录,而非用户的项目),了解输出约定、执行模式和约束。 - 根据项目的技术栈,从
../codeprobe/references/(按相同方式解析)加载适用的参考文件。 - 除非用户另有指定,否则默认使用
full模式。
错误处理与韧性检查器
领域范围
此子技能会检测以下类别中的错误处理与韧性问题:
- 吞掉异常 — 空的 catch 块、仅捕获并记录但不重新抛出或处理
- 缺少错误处理 — 外部 API 调用未使用 try/catch、未处理的 Promise 拒绝
- 错误信息 — 通用错误消息、泄露内部信息、缺少结构化响应
- 重试与熔断器 — 外部调用没有超时、瞬时故障没有重试
- 验证 — 缺少输入验证、隐式假设值非空、类型强制转换错误
- 事务安全 — 多步数据库操作未使用事务、缺少回滚
- 日志记录 — 关键路径没有日志记录、缺少关联 ID
不会标记的内容
- 日志中的敏感数据 — 由
codeprobe-security(SEC前缀)覆盖。此子技能标记的是缺少日志记录和缺少关联 ID 等结构性问题,而非数据泄露。 - 测试文件 — 测试中的异常处理遵循不同的模式,通常更简单。
- 框架生成的异常处理程序(例如 Laravel 的
Handler.php、刻意保持精简的 Next.js 错误边界)— 这些是脚手架默认内容,不是开发者疏忽。 - 错误处理刻意简单的 CLI 脚本(打印错误并退出)— 命令行工具通常会采用一种有效模式:打印错误并以非零代码退出。
- 有意吞掉特定已知无害异常且附有说明注释的 catch 块 — 如果开发者已记录原因,请尊重其决定。
- 主要属于安全漏洞的问题(例如绕过身份验证、注入、数据暴露),即使这些问题也涉及错误处理 — 这类问题由
codeprobe-security覆盖。如果两个子技能标记了同一位置,协调器会去重,并将安全问题保留为主要发现。
检测说明
吞掉异常
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
ERR | 空的 catch 块 | 搜索内容为空、只有 pass、只有 // ignored 或只有注释的 catch 块。在 JS/TS 中:catch (e) {}。在 PHP 中:catch (\Exception $e) {}。在 Python 中:except: pass 或 except Exception: pass。 | 主要 |
ERR | 仅捕获并记录,未处理 | 查找仅包含日志记录/打印语句、但不重新抛出、不返回错误,也不采取任何恢复措施的 catch 块。异常在记录后被吞掉。 | 次要 |
ERR | 捕获范围过宽的异常 | catch (\Exception $e)、catch (Exception e)、Python 中不指定类型的 except:、捕获所有错误的 catch (e)。当应捕获更具体的异常类型时标记。 | 主要 |
缺少错误处理
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ERR | 外部 API 调用未使用 try/catch | 搜索 HTTP 客户端调用(Guzzle、axios、fetch、requests、HttpClient)、支付 SDK 调用(Stripe、PayPal)、AWS SDK 调用和其他外部服务集成。标记未使用 try/catch 或 .catch() 包裹的调用。 | 主要 |
ERR | 未处理的 Promise 拒绝 | 搜索未使用 .catch() 或外围 try/catch 的异步函数或 Promise 链。查找悬空 Promise(未使用 await 的异步调用)。在 Node.js 中,检查是否缺少 unhandledRejection 处理程序。 | 主要 |
ERR | 文件 I/O 未进行错误处理 | file_get_contents、fopen、fs.readFile、open()(Python)未使用 try/catch 处理 IOError/FileNotFoundError。 | 次要 |
错误信息
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ERR | 通用错误消息 | API 响应仅返回“出了点问题”、“内部服务器错误”等类似内容,未向客户端提供错误代码或可采取行动的详细信息。 | 次要 |
ERR | 向 API 使用者泄露内部错误 | API JSON/HTML 响应中暴露异常消息、堆栈跟踪、SQL 错误或文件路径。检查错误处理中间件配置。 | 主要 |
ERR | 缺少结构化错误响应 | API 端点返回的错误缺少一致的结构(没有错误代码字段、没有消息字段,或各端点格式不一致)。 | 次要 |
重试与熔断器
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ERR | 外部服务调用未设置超时 | HTTP 客户端调用未配置超时。Guzzle 未设置 timeout 选项、axios 未设置 timeout、requests 未设置 timeout 参数、fetch 未使用 AbortController。 | 主要 |
ERR | 瞬时故障没有重试机制 | 可能发生瞬时故障的外部 API 调用(HTTP 429、503、网络错误)没有重试机制。 | 次要 |
ERR | 级联故障没有熔断器 | 微服务架构中的服务间调用没有熔断器或回退模式。 | 建议 |
验证
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ERR | 处理前未进行输入验证 | 接受外部输入(请求参数、文件内容、API 负载)的函数直接使用这些输入,未进行验证。 | 主要 |
ERR | 隐式假定值不为 null | 对可能为 null/undefined 的值访问属性或调用方法时未进行 null 检查。对可能返回 null 的值使用 . 链式访问。 | 次要 |
ERR | 类型强制转换错误 | PHP 中在安全敏感的比较中使用 == 而非 ===。JS 中使用 == 而非 ===。可能导致意外结果的隐式类型转换。 | 次要 |
事务安全
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ERR | 多步数据库操作未使用事务 | 连续执行多个 INSERT/UPDATE/DELETE 查询(同一方法中),但未使用 DB::transaction()、atomic()、BEGIN/COMMIT 或等效机制。如果任何步骤失败,数据都会处于不一致状态。 | 严重 |
ERR | 事务未正确回滚 | 事务块捕获异常但未回滚,或事务后存在假定事务成功却未检查的代码。 | 主要 |
日志记录
| ID 前缀 | 检测内容 | 检测方法 | 严重程度 |
|---|---|---|---|
ERR | 关键故障路径中没有日志记录 | 检查关键业务逻辑(支付、身份验证、订单处理)中的 catch 块,确认其中是否没有任何日志记录。故障会悄无声息地发生。 | 重大 |
ERR | 缺少关联 ID/请求 ID | 检查请求处理代码中的日志语句,确认是否缺少关联 ID、请求 ID 或跟踪 ID。这会导致无法调试分布式问题。 | 次要 |
ID 前缀和修复提示词示例
所有发现项均使用 ERR- 前缀,并按顺序编号:ERR-001、ERR-002 等。
修复提示词示例
- “在
PaymentService@charge(第 55 行)中,将 Stripe API 调用用针对\Stripe\Exception\ApiErrorException的 try/catch 包裹起来。记录包含上下文($orderId、$amount)的错误日志,并抛出带有用户友好消息的特定领域PaymentFailedException。” - “在
OrderService@create(第 40-65 行)的订单创建流程外添加DB::transaction()。该流程目前通过三次独立查询创建 Order、OrderItems 和 Payment 记录。如果任何一步失败,所有操作都应回滚。” - “将
app/Services/NotificationService.php:88处的空 catch 块替换为适当的错误处理:记录包含通知上下文的异常,然后决定是重新抛出(关键通知),还是通过指标记录后忽略(非关键通知)。” - “为
ExternalApiClient.php:30处的 HTTP 客户端调用添加超时和重试配置。对 Guzzle 请求使用->timeout(10)->retry(3, 100),以处理暂时性的网络故障。”
评论
支持 Markdown