SuperAPI AI 工具集

root-cause-tracing

测试与质量

查看项目

更新于 10-16 02:21

技能介绍

Root Cause Tracing 是一个用于调试的技能,核心理念是:当缺陷出现在调用栈深处(例如 git init 在错误目录执行、文件创建在错误位置、数据库以错误路径打开)时,不要只在错误显现处修复——那只是处理症状。正确做法是沿着调用链逐层回溯,直到找到最初的触发点,然后在源头修复。

适用场景:错误发生在深层执行阶段而非入口处;堆栈跟踪显示很长的调用链;不清楚无效数据从何而来;需要找出是哪个测试或哪段代码触发了问题。

追溯流程:

  1. 观察症状,例如 git init 在 /Users/jesse/project/packages/core 中失败。
  2. 找到直接原因:哪段代码直接导致了该错误,例如 await execFileAsync('git', ['init'], { cwd: projectDir });。
  3. 追问“是谁调用了它”:从 WorktreeManager.createSessionWorktree → Session.initializeWorkspace → Session.create → 测试中的 Project.create,逐层向上。
  4. 继续向上追溯传入的值:projectDir 是空字符串,而空字符串作为 cwd 会解析为 process.cwd(),即源码目录。
  5. 找到最初触发点:空字符串来自 setupCoreTest() 初始返回 { tempDir: '' },而测试在 beforeEach 之前就访问了 context.tempDir。

当无法手工追溯时,可添加堆栈埋点:在出问题的操作之前记录调试信息,包括 directory、cwd、NODE_ENV 和 new Error().stack。要点是:测试中应使用 console.error() 而不是 logger(logger 可能被抑制);在危险操作之前记录而非失败之后;记录足够的上下文(目录、当前工作目录、环境变量、时间戳);用 new Error().stack 捕获完整调用链。随后运行并抓取输出,例如 npm test 2>&1 | grep 'DEBUG git init',分析堆栈中的测试文件名、触发调用的行号以及规律(同一测试?同一参数?)。

若怀疑某物在测试期间产生污染但不知是哪个测试,可使用二分脚本 @find-polluter.sh,例如 ./find-polluter.sh '.git' 'src/**/*.test.ts',它会逐个运行测试并在第一个污染者处停止。

资料中的真实案例:症状是 .git 被创建在 packages/core/(源码目录)中。追溯链为 git init 在 process.cwd() 中运行(cwd 参数为空)→ WorktreeManager 收到空 projectDir → Session.create() 传入空字符串 → 测试在 beforeEach 之前访问 context.tempDir → setupCoreTest() 初始返回 { tempDir: '' }。根因是顶层变量初始化时访问了空值。修复方式是让 tempDir 成为 getter,在 beforeEach 之前被访问时抛错;同时加入纵深防御:第 1 层 Project.create() 校验目录,第 2 层 WorkspaceManager 校验非空,第 3 层 NODE_ENV 守卫拒绝在 tmpdir 之外执行 git init,第 4 层在 git init 之前记录堆栈跟踪。

关键原则:永远不要只修复错误出现的位置,要回溯找到最初触发点。找到直接原因后,若还能再向上追溯一层就继续回溯,判断是否为源头;若是源头则在源头修复,并在每一层添加校验,使缺陷无法发生。

实际效果(来自 2025-10-03 的调试记录):通过 5 层追溯找到根因,在源头(getter 校验)修复,并添加了 4 层防御,1847 个测试全部通过,零污染。

其他说明:该技能的安装方式、收费与价格、支持的平台等信息暂未提供。