console.error 不是全部 —— Output Console 捕获你看不到的错误
JustZix 的 Output Console 显示一个页面写进控制台的东西 —— 无需打开 DevTools。但很长一段时间它只显示代码通过 console.log 显式调用的东西。而你在 DevTools 里看到的一半东西根本不来自 console.log。从 2.13.86 版起这变了。
console.error 和一个错误不是一回事
容易把两件事搞混:
console.error('某事')—— 代码有意在 error 级别记录了某事。throw new Error('某事')—— 代码崩溃了。没人调用console.error。可 DevTools 还是显示一条带堆栈跟踪的红色条目。
Chrome 自己捕获崩溃并把它们显示在控制台里。如果 Output Console 只包装 console.*,那些崩溃就会从它眼前溜走 —— 而它们往往是最重要的东西,因为它们正是弄坏页面的东西。
现在会捕获什么
1. 未处理的异常
一个未处理的 throw、一个语法错误、一个运行时错误 —— Chrome 会在 window 对象上派发一个 error 事件。Output Console 监听那个事件,并连同堆栈跟踪和一个 文件:行:列 位置一起记录消息。
2. 未处理的 promise rejection
一个没有 .catch 的 someAsync().then(...),或者一个抛了错而没人捕获的 await —— Chrome 派发一个 unhandledrejection 事件。Output Console 监听它,并把 rejection 的原因显示为带「Unhandled promise rejection」前缀的 error 条目。
为什么用捕获阶段
两个监听器都挂在捕获阶段。原因:页面可能也有自己的 error 或 unhandledrejection 处理器,调用 preventDefault() 或 stopPropagation()。捕获阶段在冒泡阶段之前运行,所以 Output Console 在页面代码能把事件压下去之前就看到了它。
一个 30 秒的测试
打开一个 JS Console(或者通过 Ctrl+Alt+J 打开一个 TEMP JS Console)并输入:
throw new Error('test boom')
Output Console 里应该出现一条带堆栈跟踪的红色条目。现在:
Promise.reject('async boom')
应该出现「Unhandled promise rejection: async boom」。如果你两个都看到了 —— 错误捕获就在工作。
我们仍然不捕获什么 —— 以及为什么
- CSP 违规。它们有一个单独的
securitypolicyviolation事件 —— 以后可以加,目前在范围之外。 - 网络 4xx/5xx 错误。一个带 404 或 500 的失败
fetch是一个成功完成的响应 —— Chrome 把它显示在 Network 标签页里,不在控制台里。只有在你的代码检查response.ok后自己抛错时我们才捕获它。 - Chrome 的内部警告。像「Autofocus processing was blocked」这样的消息是浏览器自己生成的 —— 无法在页面级别拦截。
- 资源加载失败。一个失败的
<img>或<script>有时会被捕获阶段的error监听器捕获,但不总是 —— 取决于资源类型。
这些是有意的边界,不是漏洞。Output Console 显示页面的 JavaScript 错误 —— 通常你想看的东西 —— 而不是浏览器全部的诊断噪音。
使用场景 —— 不用 DevTools 的生产监控
把一个 Output Console 吸附到标签页边缘并留着它。部署后打开你的网站 —— 如果有什么崩溃了,你立刻看到,即便错误不来自你的 console.error。对一名 QA 测试员来说,这是「页面看起来 OK」和「页面看起来 OK,但后台触发了一个未处理的 TypeError」之间的区别。
另见
- Output Console —— 窗口的完整描述
- TEMP pane —— Ctrl+Alt+K 快捷键下的 Output Console
- 在 CSP 严格的页面上注入 —— 控制台钩子如何工作
安装 JustZix —— 在你的用户之前看到页面的错误。
为这篇文章评分
暂无评分 — 成为第一个。