将调试会话转化为文字地牢探险。你的bug是最终boss,堆栈帧是地牢房间,变量是战利品,日志消息是...
Dungeon Debug是一项面向实际任务的技能,主要用于“ 您站在一个暗的函数中;Exits 会导致三个接驳块和一个调回;
“ What It Doe”。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。
从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。
“你正站在一个幽暗的函数中。出口通向三个 catch 块和一个 callback。地上躺着一个名为 ‘temp2’ 的变量——它的值为 undefined。掷骰决定先攻顺序。”
调试本就是一场冒险——只是你缺少地图、生命条,以及扣人心弦的旁白叙述。Dungeon Debug 正是为此而生。
每一次调试过程,都将化身为一场基于文本的 RPG 地牢探索,其中:
这听起来荒谬绝伦。它确实荒谬绝伦。但它也切实有效——因为 RPG 框架强制你系统性地探索每个房间(即每个栈帧),防止你跳过关键环节;同时让整个调试过程足够有趣,使你不会在 45 分钟后愤而退出。
你的缺陷报告将自动生成一座地牢:
╔══════════════════════════════════════════════════════════════╗ ║ BUG #4721 的地牢 ║ ║ “幽灵空值:一个 TypeError 谜案” ║ ╠══════════════════════════════════════════════════════════════╣ ║ ║ ║ 地牢地图(由调用栈生成): ║ ║ ║ ║ [入口] ──→ [UserController.handleRequest] ║ ║ │ ║ ║ ▼ ║ ║ [AuthService.validateToken] ║ ║ │ ║ ║ ▼ ║ ║ [UserRepository.findById] ◀── 宝箱:SQL 查询 ║ ║ │ ║ ║ ▼ ║ ║ [ProfileMapper.toDTO] ← ☠ Boss 房间 ☠ ║ ║ │ ║ ║ ▼ ║ ║ 💀 TypeError: Cannot read 'email' of undefined ║ ║ ║ ║ 房间数:4 | 难度:★★★☆☆ | 预估耗时:15–30 分钟 ║ ╚══════════════════════════════════════════════════════════════╝
请选择你的调试风格:
| 职业 | 玩法 | 优势 | 劣势 |
|---|---|---|---|
| 日志师(The Logger) | 在各处插入 console.log() 作为线索 | 可观测全部数据流向 | 速度慢,输出冗杂 |
| 断点师(The Breaker) | 设置战略性断点 | 可精确检查运行时状态 | 易遗漏异步问题 |
| 阅读者(The Reader) | 运行前逐行精读代码 | 理解深入透彻 | 耗时长 |
| 逆推者(The Reverser) | 从错误出发,逆向追溯根源 | 简单缺陷定位快 | 复杂流程中易迷失方向 |
| 科学家(The Scientist) | 提出假设 → 设计实验 → 验证结果 | 方法系统严谨 | 对简单缺陷过度工程化 |
╔══════════════════════════════════════════╗ ║ 冒险者,请选择你的职业: ║ ║ ║ ║ [1] 📜 日志师 (打印一切) ║ ║ [2] 🔴 断点师 (善用断点) ║ ║ [3] 📖 阅读者 (先读再跑) ║ ║ [4] ⏪ 逆推者 (错误优先) ║ ║ [5] 🔬 科学家 (提出假设) ║ ╚══════════════════════════════════════════╝
每个调用栈帧都是一座待探索的房间:
╔══════════════════════════════════════════════════════════════╗ ║ 第 3 间房(共 4 间):UserRepository.findById() ║ ║ src/repositories/user-repository.ts:47 ║ ╠══════════════════════════════════════════════════════════════╣ ║ ║ ║ 📜 墙壁铭文(附近日志): ║ ║ “正在查询用户,id: undefined” ║ ║ 嗯……这看起来不太对劲。 ║ ║ ║ ║ 🎒 本房间道具(局部变量): ║ ║ ├── userId: undefined ← ⚠️ 可疑道具 ║ ║ ├── query: "SELECT * FROM users WHERE id = $1" ║ ║ └── result: null (查询未返回任何结果) ║ ║ ║ ║ 🚪 出口: ║ ║ ├── 返回:AuthService.validateToken(userId 的来源) ║ ║ ├── 前进:ProfileMapper.toDTO(Boss 房间) ║ ║ └── 检查:深入调查 userId 的源头 ║ ║ ║ ║ 💡 冒险者笔记: ║ ║ userId 为 undefined,查询以 undefined 为参数执行,数据库返 ║ ║ 回 null;该 null 值被传入 ProfileMapper,后者尝试访问其 ║ ║ .email 属性,从而触发错误。 ║ ║ ║ ║ Boss(TypeError)位于第 4 间房,但根本原因(ROOT CAUSE) ║ ║ 可能藏在第 2 间房(userId 赋值处),甚至第 1 间房。 ║ ║ ║ ║ 你将如何行动? ║ ║ [1] 🚪 返回第 2 间房(追踪 userId 的赋值位置) ║ ║ [2] 🚪 进入 Boss 房间(直面 TypeError) ║ ║ [3] 🔍 检查:谁调用了 findById?传入了什么参数? ║ ║ [4] 📜 阅读完整函数源码 ║ ╚══════════════════════════════════════════════════════════════╝
当你已将缺陷追查至根源时:
╔══════════════════════════════════════════════════════════════╗
║ ☠ Boss 战 ☠ ║
║ “幽灵空值”已被逼入绝境! ║
╠══════════════════════════════════════════════════════════════╣
║ ║
║ 根本原因已确认: ║
║ AuthService.validateToken() 返回的是 token payload,而非 ║
║ 用户对象。token payload 包含字段 'sub'(subject ID),而不 ║
║ 是 'userId'。控制器解构 { userId },结果得到 undefined。 ║
║ ║
║ 致命一击: ║
║ ├── 文件:src/controllers/user-controller.ts:12 ║
║ ├── 缺陷:const { userId } = await auth.validateToken(token) ║
║ ├── 修复:const { sub: userId } = await auth.validateToken() ║
║ └── 或: const { userId } = await auth.getUser(token) ║
║ ║
║ 请选择武器: ║
║ [1] ⚔️ 快速修复:将 'sub' 解构为 'userId' 别名 ║
║ [2] 🛡️ 规范修复:添加 getUser() 方法,返回完整用户对象 ║
║ [3] 🔮 防御性修复:在 findById() 中加入 null 检查 ║
║ ║
╚══════════════════════════════════════════════════════════════╝
╔══════════════════════════════════════════════════════════════╗ ║ ║ ║ ⚔️ 胜利!缺陷已被斩杀! ⚔️ ║ ║ ║ ║ 缺陷:“幽灵空值”(ProfileMapper 中的 TypeError) ║ ║ 根本原因:UserController 中解构键名错误 ║ ║ 使用武器:⚔️ 快速修复(sub → userId 别名) ║ ║ 耗时:12 分钟 ║ ║ ║ ║ 冒险统计: ║ ║ ├── 探索房间数:4/4(细致入微!) ║ ║ ├── 检查道具数:7 ║ ║ ├── 错误路径:1(最先检查了 ProfileMapper —— 干扰项) ║ ║ ├── 阅读铭文:3(日志信息非常有帮助!) ║ ║ └── 职业加成:+20% XP(逆推者 —— 错误优先策略快速命中) ║ ║ ║ ║ 获得战利品: ║ ║ ├── 💎 150 XP ║ ║ ├── 📜 知识卷轴:“Token payload 使用 'sub',而非 'userId'” ║ ║ ├── 🛡️ 教训:“务必确认鉴权函数的实际返回值” ║ ║ └── 🏆 成就进度:“Bug Squasher” 7/10 ║ ║ ║ ║ 地牢评分:★★★★☆ ║ ║ “系统性探索,回溯极少。 ║ ║ 在 Boss 房间多花了 3 分钟才向上游追踪。 ║ ║ 下次:应在直面错误前,先追踪数据流向。” ║ ║ ║ ╚══════════════════════════════════════════════════════════════╝
| RPG 机制 | 调试收益 |
|---|---|
| 探索每个房间 | 迫使你检查每个栈帧(而非直接跳到报错处) |
| 检查道具 | 促使你真正查看变量值 |
| 阅读铭文 | 促使你真正阅读日志消息 |
| 选择职业 | 让你意识到自身调试策略 |
| 记录错误路径 | 增强对认知偏差的觉察 |
| Boss 战选项 | 迫使你权衡多种修复方案 |
| 胜利统计 | 复盘总结,持续优化后续调试能力 |
调试是开发中耗时最长的环节,也是最令人沮丧、最易触发认知偏差、最易因急躁而跳过关键步骤的环节。
Dungeon Debug 并不改变你实际所做的事情——它只改变你感受这件事的方式。当调试变成一场冒险,而非一项苦差,你会探索得更彻底、思考得更富创意、也更少愤而退出。
零外部依赖。零 API 调用。纯粹由文字冒险驱动的调试体验。
相关专题
热门下载
相关下载
精品课程
共6课时 | 54.7万人学习
共89课时 | 134.1万人学习
共49课时 | 82.5万人学习