with one click
error-chain-audit
新增错误类型或错误传播路径、修改错误处理逻辑、新增异步任务(尤其是无人监听的任务)、修改错误日志输出时触发。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
新增错误类型或错误传播路径、修改错误处理逻辑、新增异步任务(尤其是无人监听的任务)、修改错误日志输出时触发。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
写入新模块文档、重构模块、或用户要求分析模块时触发。
Bug 修复或对接问题排查确认有效后,将经验记录到知识库。
修改 PMR 分配器、内存池配置、热路径容器、对象生命周期管理代码后触发。
编写或修改性能基准测试、分析 benchmark 结果、优化热路径性能时触发。
新增或修改 enable_shared_from_this 类、co_spawn 调用、shared_ptr 捕获的 lambda、co_await 后的成员访问时触发。
新增或修改原子操作、异步定时器、无锁通道、跨线程状态同步、CAS 竞争相关代码时触发。
| name | error-chain-audit |
| description | 新增错误类型或错误传播路径、修改错误处理逻辑、新增异步任务(尤其是无人监听的任务)、修改错误日志输出时触发。 |
在异步系统中,错误从产生点到最终处理点的传播链路比同步系统长得多。任何一个环节断裂——信息丢失、无人监听、上下文不足——都会导致故障无法定位、异常状态无法清理、或资源泄漏。本 skill 审计的是错误传播链路的完整性,而非特定的错误表示形式。
无论错误用枚举、异常、expected<T,E> 还是其他方式表示,三个不变量始终成立:
异步系统中存在"发射后不管"的任务——启动者不等待其完成,也不接收其结果。这类任务中的错误没有外部接收者,如果不自行处理,错误会触发进程级终止。每个无人监听的任务都必须在内部完整处理所有可能的失败路径。
| 检查项 | 说明 |
|---|---|
| 每个错误可描述 | 系统中每种可发生的错误是否都有人类可读的描述。新增错误类型时是否同步更新描述。不可描述的错误在日志中表现为无意义的标识符,使排查无法进行 |
| 无死类型 | 是否存在定义了但从未产生的错误类型。死类型增加理解成本,且可能是遗漏的功能或残留的重构痕迹 |
| 无语义重叠 | 不同错误类型之间是否存在语义重叠。重叠会导致调用方无法区分具体错误,影响处理策略。如果两种错误总是被同一方式处理,考虑合并 |
| 底层错误不穿透 | 底层错误(操作系统、TLS 库、网络栈)是否被转换为业务语义的错误类型后传播,而非以原始形式穿透到上层。原始错误码对上层无意义,且会泄漏底层实现细节 |
| 检查项 | 说明 |
|---|---|
| 转换覆盖完整 | 从底层错误到业务错误的转换是否覆盖了所有常见值。未转换的底层错误需要一个合理的兜底策略,而非静默忽略 |
| TLS 错误的特殊处理 | TLS 相关错误(连接截断、握手失败、解密失败、证书无效)是否有专门的转换。TLS 错误通常需要特殊处理(回落、重新握手),笼统转换会丢失处理机会 |
| 转换不丢信息 | 错误从一层转换到另一层时,是否保留了足够的原始信息供排查。如果转换后原始错误码丢失,排查时无法追溯到根因 |
| 转换方向明确 | 错误转换的方向是否一致——总是从底层到上层转换,而非混合方向。混合方向的转换链难以追踪 |
| 检查项 | 说明 |
|---|---|
| 内部完整处理 | 每个无人监听的异步任务是否在内部捕获并处理所有可能的失败。必须同时处理已知错误类型和未知错误(兜底捕获),未知错误尤其需要记录类型信息 |
| 处理不丢信息 | 错误处理是否记录了足够的信息(类型、描述、发生位置)。静默处理(空处理块)等同于丢弃错误——如果错误不值得记录,那它是否值得处理 |
| 是否应改为有人监听 | 对于需要外部感知成功/失败的任务,是否应改为有人监听的模式。无人监听只适用于"真正的后台任务"(如日志刷入、指标聚合) |
| 资源释放 | 错误路径上是否正确释放了所有已获取的资源(连接、缓冲区、定时器)。错误处理不得跳过任何 RAII 析构 |
| 检查项 | 说明 |
|---|---|
| 日志级别合理 | 预期内的错误(如对端关闭、超时、取消)使用低级别;意外错误(如内存不足、内部状态不一致)使用高级别。过度使用高级别会导致运维疲劳,忽略真正严重的问题 |
| 上下文充足 | 日志中是否包含足够的上下文用于排查:操作类型、相关标识符、错误描述。仅有 "operation failed" 的日志无法定位问题。但也不要过度——日志不应包含完整调用栈 |
| 不泄漏敏感信息 | 错误日志是否遵循信息泄漏审计的要求——不包含密钥材料、不暴露实现特有的错误格式。参见 leak-audit |
| 调试日志的安全性 | 调试级别的日志是否可能包含敏感信息。调试日志在开发阶段有用,但生产构建中必须确保不输出。参见 leak-audit 日志安全节 |
| 检查项 | 说明 |
|---|---|
| 热路径不抛异常 | 数据转发、协议处理等热路径是否使用返回值传播错误,而非抛异常。异常在热路径中引入非确定性的性能抖动,且在异步环境中传播栈可能不准确 |
| 异常类型层次 | 自定义异常类型是否形成了合理的层次结构。基类提供通用信息,派生类提供领域特定信息。扁平的异常类型(每种错误一个独立类)增加维护成本 |
| 错误信息安全 | 错误的描述信息是否包含敏感数据(地址、域名、密钥)。错误信息可能被记录到日志或包含在错误响应中 |
// ❌ 无人监听的任务未处理错误 — 可能触发进程终止
spawn_background_task(async_task);
// ✅ 无人监听的任务内部完整处理所有错误
spawn_background_task([]()
-> task<void>
{
try
{
co_await async_task();
}
catch (const std::exception& e)
{
log_warn("后台任务失败: {}", e.what());
}
catch (...)
{
log_error("后台任务失败: 未知错误");
}
});
// ❌ 日志无上下文 — 无法定位问题
log_error("operation failed");
log_warn("connection closed");
// ✅ 日志包含操作类型和标识符
log_warn("隧道关闭: {} -> {}, 入流量={}, 出流量={}, 原因={}",
client_addr, target_addr, bytes_in, bytes_out,
describe(error));
// ❌ 底层错误码直接穿透到上层 — 上层无法理解
log_error("ssl error: {}", raw_platform_error_code);
// ✅ 转换为业务语义的错误并保留原始信息供排查
log_error("TLS 握手失败: {} (详情: {})", describe(business_error), platform_error.message());
// ❌ 空 catch 块 — 吞掉错误,排查时无迹可寻
try
{
co_await process_frame();
}
catch (...)
{
// 什么都不做
}
// ✅ 至少记录错误类型
try
{
co_await process_frame();
}
catch (const std::exception& e)
{
log_warn("帧处理失败: {}", e.what());
}
// ❌ 数据转发路径中抛异常 — 非确定性性能抖动
auto plaintext = decrypt(ciphertext);
// decrypt 内部 throw protocol_error("tag mismatch")
// ✅ 热路径使用返回值传播错误
auto result = decrypt(ciphertext);
if (!result)
{
return result.error();
}
coroutine-audit 覆盖了异步任务的正确启动模式维度co-lifecycle-audit 覆盖了错误路径上的对象析构和资源释放维度leak-audit 覆盖了错误日志中的信息泄漏风险维度crypto-audit 覆盖了密码学错误的特殊处理(AEAD 验证失败、nonce 耗尽)维度enforce-coding Rule 13 定义了 fault::code vs exception 的使用边界,本 skill 审计传播链完整性concurrency-audit 覆盖了 CAS 失败降级的错误处理、通道关闭后的错误传播维度pool-audit 覆盖了 checkout 失败时的错误传播、健康检查失败的驱逐维度tunnel-audit 覆盖了双向转发中的写入失败传播、所有退出路径的统计 flush 维度mux-audit 覆盖了帧处理错误的协议错误帧发送、流异常退出通知维度