try—catch

只能捕获同步的运行时错误,对语法、异步错误无能为力,用来可预见情况下的特定错误监控

window.onerror

JS 运行错误发生时,window 会触发一个 ErrorEvent 接口的 error 事件,并执行 window.onerror()。

1
2
3
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到异常:', {message, source, lineno, colno, error});
}

window.onerror 函数只有在返回 true 的时候,异常才不会向上抛出,写在所有 js 脚本前面,捕获意料之外的错误(静态资源错误、接口错误)

addEventListener

加载资源失败时,加载资源的元素会触发 Event 接口的 error 事件,并执行该元素上的 onerror 处理函数,error 事件不会向上冒泡到 window

1
2
3
window.addEventListener('error', (error) => {
console.log('捕获到异常:', error);
}, true)

注意点:
1. 不同浏览器返回 error 对象不同,考虑兼容
2. 避免 addEventListener 重复监听

Promise Catch

捕获异步 error,没有写 catch 的 Promise 抛出的错误无法被 onerror、try-catch 捕获

漏写 catch 解决方案

全局增加一个对 unhandledrejection 的监听,用来全局监听 Uncaught Promise Error

1
2
3
4
5
6
window.addEventListener("unhandledrejection", function(e){
e.preventDefault() // 去掉控制台的异常显示
console.log('捕获到异常:', e);
return true;
});
Promise.reject('promise error');

VUE errorHandler 和 React componentDidCatch

页面崩溃

  1. window 对象的 load、beforeunload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
window.addEventListener('load', function () {
sessionStorage.setItem('good_exit', 'pending');
setInterval(function () {
sessionStorage.setItem('time_before_crash', new Date().toString());
}, 1000);
});

window.addEventListener('beforeunload', function () {
sessionStorage.setItem('good_exit', 'true');
});

if(sessionStorage.getItem('good_exit') &&
sessionStorage.getItem('good_exit') !== 'true') {
/*
insert crash logging code here
*/
alert('Hey, welcome back from your crash, looks like you crashed on: '
+ sessionStorage.getItem('time_before_crash'));
}
  1. Service Worker

特点:
+ 独立线程
+ 生命周期比网页长

navigator.serviceWorker.controller.postMessage

错误上报

  1. ajax

  2. 动态创建 img

    利用 new Image().src 实现上报,控制采集率,达到缓解服务器压力的作用