根本原因追踪 root-cause-tracing

这个技能用于在软件开发中通过系统性地回溯调用栈来找到错误的原始触发点,适用于深度执行错误和长调用链场景,帮助识别污染源和提升调试效率。关键词:根本原因追踪、调用栈、调试、错误处理、软件测试、回溯分析、代码质量。

测试 0 次安装 0 次浏览 更新于 3/7/2026

name: root-cause-tracing description: 系统性地通过调用栈回溯追踪错误以找到原始触发器。当错误在执行深处发生时,并且您需要回溯以找到原始触发器时使用。 version: 1.1.0

根本原因追踪

概述

错误经常在调用栈深处显现(例如 git init 在错误目录、文件创建在错误位置、数据库以错误路径打开)。您的本能是在错误出现的地方修复,但这只是治标。

核心原则: 通过调用链回溯,直到找到原始触发器,然后在源头上修复。

何时使用

使用时机:

  • 错误发生在执行深处(非入口点)
  • 堆栈跟踪显示长调用链
  • 不清楚无效数据源自何处
  • 需要找到触发问题的测试/代码

追踪过程

1. 观察症状

Error: git init failed in ~/project/packages/core

2. 找到直接原因

什么代码直接导致此错误?

await execFileAsync('git', ['init'], { cwd: projectDir });

3. 询问:什么调用了此代码?

WorktreeManager.createSessionWorktree(projectDir, sessionId)
  → called by Session.initializeWorkspace()
  → called by Session.create()
  → called by test at Project.create()

4. 持续向上追踪

传递了什么值?

  • projectDir = '' (空字符串!)
  • 空字符串作为 cwd 解析为 process.cwd()
  • 那是源代码目录!

5. 找到原始触发器

空字符串来自哪里?

const context = setupCoreTest(); // Returns { tempDir: '' }
Project.create('name', context.tempDir); // Accessed before beforeEach!

添加堆栈跟踪

当无法手动追踪时,添加检测:

// 在有问题的操作之前
async function gitInit(directory: string) {
  const stack = new Error().stack;
  console.error('DEBUG git init:', {
    directory,
    cwd: process.cwd(),
    nodeEnv: process.env.NODE_ENV,
    stack,
  });

  await execFileAsync('git', ['init'], { cwd: directory });
}

关键: 在测试中使用 console.error()(而不是 logger - 可能不显示)

运行并捕获:

bun test 2>&1 | grep 'DEBUG git init'

分析堆栈跟踪:

  • 查找测试文件名称
  • 找到触发调用的行号
  • 识别模式(相同测试?相同参数?)

找到导致污染的测试

如果某些东西在测试期间出现,但不知道是哪个测试:

使用二分脚本逐个运行测试:

# 示例:找到哪个测试在错误位置创建 .git
bun test --run --bail 2>&1 | tee test-output.log

逐个运行测试,在第一个污染者处停止。

真实示例:空 projectDir

症状: .git 创建在 packages/core/(源代码)

追踪链:

  1. git initprocess.cwd() 中运行 ← 空的 cwd 参数
  2. WorktreeManager 以空 projectDir 调用
  3. Session.create() 传递空字符串
  4. 测试在 beforeEach 之前访问 context.tempDir
  5. setupCoreTest() 最初返回 { tempDir: '' }

根本原因: 顶级变量初始化访问空值

修复: 使 tempDir 成为 getter,如果在 beforeEach 之前访问则抛出异常

还添加了深度防御:

  • 第1层:Project.create() 验证目录
  • 第2层:WorkspaceManager 验证非空
  • 第3层:NODE_ENV 保护拒绝在 tmpdir 外 git init
  • 第4层:在 git init 之前记录堆栈跟踪

关键原则

永远不要只在错误出现的地方修复。 回溯以找到原始触发器。

堆栈跟踪技巧

在测试中: 使用 console.error() 而不是 logger - logger 可能被抑制 在操作之前: 在危险操作之前记录,而不是在失败之后 包括上下文: 目录、cwd、环境变量、时间戳 捕获堆栈: new Error().stack 显示完整调用链

现实世界影响

从调试会话中:

  • 通过5级追踪找到根本原因
  • 在源头上修复(getter 验证)
  • 添加了4层防御
  • 1847个测试通过,零污染