Java 异常诊断 (ym-java-exception-triage)
按堆栈证据给 Java 异常定位根因,每条结论都能回溯到具体一行,并严格区分「已证实」和「待验证」——普通对话最容易把「可能」说成「就是」,还爱编运行结果,这里用标签和证据链堵住。
何时使用
- 用户说「这个报错什么意思」「看看这个堆栈」「线上报了这个异常」「Java 报错」「看堆栈」「异常定位」「exception」「stacktrace」时
- 用户贴了 Spring Boot / MyBatis / JPA 的异常堆栈,问「为什么炸」「第几行的问题」时
运行前提
- 依赖:无第三方库,纯文本分析。
- 不执行代码、不连接服务器、不读取项目文件(除非用户明确给路径)。
- 不联网、不上传任何数据;堆栈可能含内网地址、包名、账号等敏感信息,提醒用户粘贴前脱敏。
输入契约
| 项 | 必需 | 说明 |
|---|---|---|
| 异常堆栈 | 必需 | 可含 Caused by 链;越完整越好 |
| JDK 版本 | 强烈建议 | 如 17.0.9;缺则按通用情况分析并标注「未确认版本」 |
| 框架及版本 | 强烈建议 | 如 Spring Boot 3.2、MyBatis 3.5 |
| 相关代码片段 | 强烈建议 | 出错类/方法;缺则只基于堆栈分析,不臆测业务代码逻辑 |
| 复现步骤 | 强烈建议 | 帮助锁定触发条件 |
缺失处理:
- 缺版本 → 按通用情况分析,所有结论标注「未确认版本」。
- 缺代码 → 只基于堆栈说话,不猜测业务代码里发生了什么。
- 只有一句「报错了」没有堆栈 → 列出需要补充的四项信息(完整堆栈 / 版本 / 框架 / 相关代码),不猜。
执行步骤
-
解析异常链 — 找最内层
Caused by(根因通常在最里面,不是最上面那行)。判定规则见references/exception-patterns.md第一节。 -
提取关键证据 — 异常类型、异常消息、出错的类与方法、行号、框架包名。把这些信息原样列出,作为后续所有结论的锚点。
-
区分帧类型 — 标出第一个业务帧,区分三方框架帧与业务帧,圈定「问题很可能落在哪个业务方法」。规则见 references 第二节。
-
列候选根因 — 每条必须含:根因假设 / 支持它的证据(堆栈具体行)/ 反驳它的证据 / 最小验证步骤。参考 references 第三节的速查表找方向,但必须回用户堆栈取证据。
-
打状态标签 — 每条根因标 【已证实】(堆栈里能直接读到)或 【待验证】(需跑一下才知道)。这是本技能最硬的设计,缺标签不准输出。规则见 references 第四节。
-
给最小验证步骤 — 具体到「在哪个类哪行加什么日志、打什么断点、执行什么命令」,禁止写「检查一下配置」。参考 references 第五节。
-
修复建议放验证后 — 针对已证实根因给改法并标风险;针对待验证根因的改法必须注明「未经验证,不要直接上生产」。
-
硬性约束:不编造运行结果;不把「可能」写成「就是」;不输出没有任何对应证据的根因;堆栈被截断时明确说信息不足并列出待补内容。
输出格式
Markdown,套用 templates/triage-report-template.md:
## 一句话结论
## 异常链解读
## 候选根因(表:假设 / 状态 / 支持证据 / 反驳证据 / 验证步骤)
## 最小验证清单
## 修复建议(标注风险)
能力边界
- 不执行代码、不连接服务器、不读取项目文件(除非用户明确给路径)。
- 不自动改代码、不替用户发版。
- 不做堆内存 dump 深度分析(
OutOfMemoryError只能给方向,不能替代 MAT 分析)。 - 不声称覆盖所有 Java 技术栈;首版聚焦 Spring Boot / MyBatis / JPA 常见异常。
常见坑
- 根因找错层 — 现象:盯着最外层
ServletException给结论,修了一通没用。原因:没往Caused by最内层找。规避:先定位最内层Caused by,它才是根因。 - 把「可能」写成「就是」 — 现象:堆栈只显示超时,模型直接下结论「连接池耗尽」。原因:用推测代替证据。规避:凡需运行才能确认的,一律标【待验证】并给验证步骤。
- 臆测业务代码 — 现象:用户没给代码,模型编出「你这里少写了个判空」。原因:把自己当成代码作者。规避:缺代码时只基于堆栈分析,明确说「未看到相关代码,以下为基于堆栈的推测」。
- 验证步骤写空话 — 现象:写「检查一下配置是否正确」。原因:没落到动作。规避:必须到「在 X 类第 N 行加日志打印 Y 变量」这种粒度。
- 不分三方帧与业务帧 — 现象:根因归到
org.springframework内部,其实是用错了。原因:没区分帧类型。规避:优先圈定第一个业务帧;三方包内部异常先按「用法错误」排查(见 references 第六节)。 - 截断堆栈硬编 — 现象:用户只贴了最外层一行,模型编出完整调用链。原因:把猜测当事实。规避:信息不足就明说,列出需要补充的四项信息,不猜。
验收用例
- 正常:Spring Boot + MyBatis 的
NullPointerException完整堆栈 → 定位到具体 Mapper/方法,给出验证步骤,根因带【已证实】。 - 边界 1:堆栈被截断只剩最外层 → 明确说明信息不足,列出需要补充的部分。
- 边界 2:异常来自三方包内部 → 区分「用法错误 / 版本不兼容 / 三方 bug」三种可能,默认先归用法错误。
- 失败:用户只说「报错了」→ 不猜,列出需要补充的四项信息。
目录说明
references/exception-patterns.md— 异常链解析、帧分类、常见异常速查、状态标签与验证步骤规范templates/triage-report-template.md— 诊断报告输出模板