直接方式有 try...catch 和 window.onerror(addEventListener) 两种
try { init(); // code... } catch(e){ Reporter.send(format(e)); }
/** * @param {String} errorMessage 错误信息 * @param {String} scriptURI 出错的文件 * @param {Long} lineNumber 出错代码的行号 * @param {Long} columnNumber 出错代码的列号 * @param {Object} errorObj 错误的详细信息,Anything */ window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) { // code.. } window.addEventListener('error', (e) => { console.log(e); }, true);
addEventListener 还可以捕获资源加载错误、未 catch 的 promise 错误。如下:PS: addEventListener和onerror两种方式收集的信息不太一致,整体addEventListener信息更多更细
// 捕获未 catch 的 promise 错误 window.addEventListener("unhandledrejection", e => { e.preventDefault(); console.log(e); });
局限
try...catch
- 为所有可能的代码加上try...catch显然不太明智;
- 不能捕获异步代码发生的错误
Window.onerror
- 跨域文件的报错无具体报错信息,Script error.简单报错;
- 压缩代码无法定位到错误的具体位置;
- 收集日志的量需要做额外的处理
- 缺少友好的错误提示;
PS: window.onerror事件的监听须保证在最前头执行;
合理的处理方案是进行部分精确的埋点收集(点击事件、不同请求响应码)
框架提供的错误收集
React 16之后的react componentDidCatch钩子
componentDidCatch(error, info) {
console.log(error, info);
}
Vue 2.2.0+ 后的vue errorHandler
Vue.config.errorHandler = function (err, vm, info) { // handle error // `info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子 // 只在 2.2.0+ 可用 }
参考:
https://www.cnblogs.com/hustskyking/p/fe-monitor.html
https://zhuanlan.zhihu.com/p/47749670