name: root-cause-tracing description: 当错误在深层执行中发生时,您需要追溯以找到原始触发点 - 通过调用堆栈系统性地向后追踪bug,需要时添加仪器,以识别无效数据或错误行为的来源
根因追踪:追溯源头
1. 核心原则
- 修复源头,而非症状: 永远不要只在错误出现的地方打补丁。通过调用堆栈向后追溯,直到找到原始触发点。
2. 系统性追溯
- 观察症状: 识别确切的失败点(例如,git init失败)。
- 直接原因: 找到执行失败操作的代码行。
- 反向调用链: 使用堆栈跟踪查看哪个函数调用了它,以及哪个调用了那个(例如,Test -> Project.create() -> Session.init() -> exec())。
- 数据来源: 识别哪个变量是无效的(空字符串、null等),并找到它被初始化或修改的确切位置。
3. 仪器化(当手动追溯失败时)
如果来源不清晰,在失败操作之前注入临时调试日志:
// 示例仪器化
console.error("DEBUG TRACE:", {
input,
cwd: process.cwd(),
stack: new Error().stack
});
- 专业提示: 在测试中使用console.error以绕过标准日志抑制。
4. 深度防御
一旦源头被修复,应用多层验证:
- 层1: 修复原始触发点(例如,更改变量为抛出错误的getter)。
- 层2: 在每个中间函数的入口点添加输入验证。
- 层3: 添加环境防护(例如,“拒绝在源代码目录中运行”)。
5. 验证策略
- 单元测试: 仅为复杂逻辑或数据转换编写确定性测试。
- 手动/代码检查: 对于简单的UI更改或CRUD,跳过测试;依赖类型检查和手动验证。
6. 追溯流程
- 找到原因? -> 能否向上追溯一级?
- 是: 向后追溯。
- 否(达到源头): 在此处修复 并 在每一层下方添加验证。
- 结果: bug变得无法复现。
关键: 修复症状而不找到触发点是一种“死胡同”修复。始终追踪原始调用者。