mcpField
B
bug-hunter

bug-hunter

github.com/sickn33开发48.9k129 次安装今天更新
代码仓库

关于 bug-hunter

bug-hunter 是面向开发者的调试技能,用于调查错误、异常行为和生产问题。它引导流程从复现和收集证据,延伸到根因修复、验证、回归测试与记录。

主要功能

  1. 01稳定复现故障
  2. 02收集日志与错误详情
  3. 03验证基于证据的假设
  4. 04追查并修复根因
  5. 05验证修复并防止回归
  6. 06运用调试技巧与工具

适用场景

  1. 01调查间歇性生产故障
  2. 02从错误现象追溯根因
  3. 03针对边界情况测试修复
  4. 04修复后补充回归测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill bug-hunter

安装后在 Claude Code 中输入/bug-hunter确认已加载。

附带文件README.md

详细介绍

Bug Hunter

使用经过验证的调试技巧,系统地查找并修复 Bug。不要猜测——以证据为依据。

何时使用此技能

  • 用户报告 Bug 或错误
  • 某些功能未按预期运行
  • 用户说“修复 Bug”或“调试一下”
  • 间歇性故障或异常行为
  • 需要调查生产环境问题

调试流程

1. 重现 Bug

首先,稳定地复现问题:

1. Get exact steps to reproduce
2. Try to reproduce locally
3. Note what triggers it
4. Document the error message/behavior
5. Check if it happens every time or randomly

如果无法复现,请收集更多信息:

  • 什么环境?(开发、预发布、生产)
  • 使用什么浏览器/设备?
  • 发生问题前用户执行了哪些操作?
  • 有错误日志吗?
2. 收集证据

收集所有可用信息:

检查日志:

# Application logs
tail -f logs/app.log

# System logs
journalctl -u myapp -f

# Browser console
# Open DevTools → Console tab

检查错误消息:

  • 完整的堆栈跟踪
  • 错误类型和消息
  • 行号
  • 时间戳

检查状态:

  • 正在处理什么数据?
  • 用户当时想做什么?
  • 数据库里有什么?
  • 本地存储/ Cookie 中有什么?
3. 提出假设

根据证据,推测问题所在:

"The login times out because the session cookie 
expires before the auth check completes"

"The form fails because email validation regex 
doesn't handle plus signs"

"The API returns 500 because the database query 
has a syntax error with special characters"
4. 验证假设

证实或证伪你的猜测:

添加日志:

console.log('Before API call:', userData);
const response = await api.login(userData);
console.log('After API call:', response);

使用调试器:

debugger; // Execution pauses here
const result = processData(input);

隔离问题:

// Comment out code to narrow down
// const result = complexFunction();
const result = { mock: 'data' }; // Use mock data
5. 找到根本原因

追查问题的真正原因:

常见根本原因:

  • Null/undefined 值
  • 数据类型错误
  • 竞态条件
  • 缺少错误处理
  • 逻辑错误
  • 差一错误
  • Async/await 问题
  • 缺少验证

追踪示例:

Symptom: "Cannot read property 'name' of undefined"
↓
Where: user.profile.name
↓
Why: user.profile is undefined
↓
Why: API didn't return profile
↓
Why: User ID was null
↓
Root cause: Login didn't set user ID in session
6. 实施修复

修复根本原因,而非表面症状:

错误的修复(针对症状):

// Just hide the error
const name = user?.profile?.name || 'Unknown';

正确的修复(针对根本原因):

// Ensure user ID is set on login
const login = async (credentials) => {
  const user = await authenticate(credentials);
  if (user) {
    session.userId = user.id; // Fix: Set user ID
    return user;
  }
  throw new Error('Invalid credentials');
};
7. 测试修复

验证修复确实有效:

1. Reproduce the original bug
2. Apply the fix
3. Try to reproduce again (should fail)
4. Test edge cases
5. Test related functionality
6. Run existing tests
8. 防止回归

添加测试,防止问题再次出现:

test('login sets user ID in session', async () => {
  const user = await login({ email: '[email protected]', password: 'pass' });
  
  expect(session.userId).toBe(user.id);
  expect(session.userId).not.toBeNull();
});

调试技巧

二分查找

反复将问题范围缩小一半:

// Does the bug happen before or after this line?
console.log('CHECKPOINT 1');
// ... code ...
console.log('CHECKPOINT 2');
// ... code ...
console.log('CHECKPOINT 3');
橡皮鸭调试法

大声逐行解释代码。解释时,你往往会发现问题所在。

打印调试

在合适的位置添加 console.logs:

console.log('Input:', input);
console.log('After transform:', transformed);
console.log('Before save:', data);
console.log('Result:', result);
差异调试

比较正常运行与故障状态:

  • 最近有什么变更?
  • 不同环境之间有什么差异?
  • 数据有什么不同?
时间回溯调试

使用 git 查找问题从何时开始:

git bisect start
git bisect bad  # Current commit is broken
git bisect good abc123  # This old commit worked
# Git will check out commits for you to test

常见 Bug 模式

Null/Undefined
// Bug
const name = user.profile.name;

// Fix
const name = user?.profile?.name || 'Unknown';

// Better fix
if (!user || !user.profile) {
  throw new Error('User profile required');
}
const name = user.profile.name;
竞态条件
// Bug
let data = null;
fetchData().then(result => data = result);
console.log(data); // null - not loaded yet

// Fix
const data = await fetchData();
console.log(data); // correct value
差一错误
// Bug
for (let i = 0; i <= array.length; i++) {
  console.log(array[i]); // undefined on last iteration
}

// Fix
for (let i = 0; i < array.length; i++) {
  console.log(array[i]);
}
类型强制转换
// Bug
if (count == 0) { // true for "" and []; false for null
  
// Fix
if (count === 0) { // only true for 0
Async 未使用 Await
// Bug
const result = asyncFunction(); // Returns Promise
console.log(result.data); // undefined

// Fix
const result = await asyncFunction();
console.log(result.data); // correct value

调试工具

浏览器 DevTools
Console: View logs and errors
Sources: Set breakpoints, step through code
Network: Check API calls and responses
Application: View cookies, storage, cache
Performance: Find slow operations
Node.js 调试
// Built-in debugger
node --inspect app.js

// Then open chrome://inspect in Chrome
VS Code 调试
// .vscode/launch.json
{
  "type": "node",
  "request": "launch",
  "name": "Debug App",
  "program": "${workspaceFolder}/app.js"
}

遇到瓶颈时

  1. 休息一下(真的,离开 10 分钟)
  2. 向别人解释问题(或者对着橡皮鸭说)
  3. 搜索完整的错误消息
  4. 检查这是否是已知问题(GitHub issues、Stack Overflow)
  5. 简化问题:创建最小复现示例
  6. 重新开始:删除并重写有问题的代码
  7. 寻求帮助(提供背景信息,以及你尝试过的方法)

文档模板

修复后,记录问题:

## Bug: Login timeout after 30 seconds

**Symptom:** Users get logged out immediately after login

**Root Cause:** Session cookie expires before auth check completes

**Fix:** Increased session timeout from 30s to 3600s in config

**Files Changed:**
- config/session.js (line 12)

**Testing:** Verified login persists for 1 hour

**Prevention:** Added test for session persistence

核心原则

  • 先复现,再修复
  • 依据证据,不要猜测
  • 修复根本原因,而非表面症状
  • 彻底测试修复效果
  • 添加测试以防止回归
  • 记录你学到的内容

相关技能

  • @systematic-debugging - 高级调试
  • @test-driven-development - 测试
  • @codebase-audit-pre-push - 代码审查

限制

  • 仅当任务明确符合上述范围时,才使用此技能。
  • 不要将输出视为环境特定验证、测试或专家审查的替代品。
  • 如果缺少必需的输入、权限、安全边界或成功标准,请暂停并请求澄清。

仅记录允许列表中的非机密诊断信息;userData、身份验证载荷和完整响应可能包含令牌或私人记录。添加日志前,请在经授权的隔离环境中复现。使用干净的一次性检出副本运行 git bisect,记录实际的良好/不良修订版本,并在之后运行 git bisect reset;保留用户更改。优先采用有证据支持的最小修复,而不是一概删除或重写,并区分示例测试输出与实际观察到的结果。

评论

支持 Markdown