示例:异步错误
window.onerror = function (msg, url, row, col, error) {
console.log('我知道异步错误了');
console.log({
msg, url, row, col, error
})
return true;
};
setTimeout(() => {
error;
});
然而 window.onerror 对于语法错误还是无能为力,所以我们在写代码的时候要尽可能避免语法错误的,不过一般这样的错误会使得整个页面崩溃,还是比较容易能够察觉到的。
在实际的使用过程中,onerror 主要是来捕获预料之外的错误,而 try-catch 则是用来在可预见情况下监控特定的错误,两者结合使用更加高效。
需要注意的是,window.onerror 函数只有在返回 true 的时候,异常才不会向上抛出,否则即使是知道异常的发生控制台还是会显示 Uncaught Error: xxxxx。
关于 window.onerror 还有两点需要值得注意
对于 one rror 这种全局捕获,最好写在所有 JS 脚本的前面,因为你无法保证你写的代码是否出错,如果写在后面,一旦发生错误的话是不会被 one rror 捕获到的。另外 one rror 是无法捕获到网络异常的错误。
当我们遇到
报 404 网络请求异常的时候,onerror 是无法帮助我们捕获到异常的。
<script>
window.onerror = function (msg, url, row, col, error) {
console.log('我知道异步错误了');
console.log({
msg, url, row, col, error
})
return true;
};
script>
<img src="./404.png">
由于网络请求异常不会事件冒泡,因此必须在捕获阶段将其捕捉到才行,但是这种方式虽然可以捕捉到网络请求的异常,但是无法判断 HTTP 的状态是 404 还是其他比如 500 等等,所以还需要配合服务端日志才进行排查分析才可以。
<script>
window.addEventListener('error', (msg, url, row, col, error) => {
console.log('我知道 404 错误了');
console.log(
msg, url, row, col, error
);
return true;
}, true);
script>
<img src="./404.png" alt="">
这点知识还是需要知道,要不然用户访问网站,图片 CDN 无法服务,图片加载不出来而开发人员没有察觉就尴尬了。
Promise 错误
通过 Promise 可以帮助我们解决异步回调地狱的问题,但是一旦 Promise 实例抛出异常而你没有用 catch 去捕获的话,onerror 或 try-catch 也无能为力,无法捕捉到错误。
window.addEventListener('error', (msg, url, row, col, error) => {
console.log('我感知不到 promise 错误');
console.log(
msg, url, row, col, error
);
}, true);
Promise.reject('promise error');
new Promise((resolve, reject) => {
reject('promise error');
});
new Promise((resolve) => {
resolve();
}).then(() => {
throw 'promise error'
});