-
Notifications
You must be signed in to change notification settings - Fork 1
Description
常见错误
- 脚本错误
- 语法错误
- 运行时错误
- 同步错误
- 异步错误
- Promise 错误
- 网络错误
- 资源加载错误
- 自定义请求错误
语法错误
语法错误无法被try catch 处理,但是一般在开发时就很容易被发现。
同步错误
JS 引擎在执行脚本时,把任务分块压入事件栈,轮询取出执行,每个事件任务都有自己的上下文环境, 在当前上下文环境同步执行的代码发生错误都能被try catch 捕获,保证后续的同步代码被执行。
try {
// error
} catch (e) {
console.log(e);
}异步错误
常见的 setTimeout 等方法会创建新的事件任务插入事件栈中,待后续执行。 所以try catch 无法捕获其他上下文的代码错误。
为了便于分析发生的错误,一般利用 window.onerror 事件来监听错误的发生。 它比try catch的捕获错误信息的能力要强大。
/**
* @param {Event|string} msg 错误描述
* @param {?string} url 报错文件
* @param {?number} row 行号
* @param {?number} col 列号
* @param {?Error} error 错误Error对象
*/
window.onerror = function (msg, url, row, col, error) {
console.log('window.onerror =>', arguments);
// return true; // 返回 true 的时候,异常不会向上抛出,控制台不会输出错误
};注意事项
window.onerror可以捕获常见语法、同步、异步错误等错误;window.onerror无法捕获Promise错误、网络错误;window.onerror应该在所有 JS 脚本之前被执行,以免遗漏;window.onerror容易被覆盖,在处理回调时应该考虑,被人也在使用该事件监听。
Promise 错误
如果你在使用 promise 时未 catch 的话,那么 onerror 也无能为力了。
Promise.reject('this is reject');
new Promise((resolve, reject) => {
reject('promise error');
});
new Promise((resolve) => {
resolve();
}).then(() => {
throw 'promise error';
});同样你可以利用 window.onunhandledrejection 或 window.addEventListener("unhandledrejection")来监控错误。 接收一个PromiseError对象,可以解析错误对象中的 reason 属性,有点类似 stack。
window.onunhandledrejection = function () {
console.log('window.onunhandledrejection => ', arguments);
};具体兼容处理在 TraceKit.js 可以看到。
网络错误
由于网络请求异常不会冒泡,应此需要在事件捕获阶段才能获取到。 我们可以利用 window.addEventListener。比如代码、图片等重要 CDN 资源挂了,能及时获得反馈是极为重要的。
window.addEventListener(
'error',
({ target }) => {
if (target === window) return; // 避免重复上报
console.log({
url: location.href, // 引用资源地址
src: target.src, // 资源加载出错地址
tagName: target.tagName,
});
// return true; // 中断事件传播
},
true
);window.addEventListener 的好处,不怕回调被覆盖,可以监听多个回调函数,但记得销毁避免内存泄漏与错误。
但无法获取 window.onerror 那么丰富的信息。一般只用window.addEventListener 来监控资源加载错误。
上报方式
参考 badjs
同过将错误信息拼接到 url 中,借助img发起请求上报;或者通过传入处理方法,一般使用ajax。
由于 get 请求参数有长度限制,数据太大还是使用post更加稳妥。
- 关于的 Script Error 处理 Script error BetterJS/badjs-report#3


