前端错误监控以及上报方法总结

捕获错误的常见的几种方法

Global​Event​Handlers​.onerror
windows下面的全局error事件程序,当有javaSript脚本运行错误或者资源<img>、<script>加载失败时,都会触发Event接口的error事件,也能被window.addEventListener捕获到

两种写法前端

window.onerror = function(message, source, lineno, colno, error) { 
    console.log(message)//字符串错误信息
    console.log(source)//发生错误的脚本
    console.log(lineno)//发生错误的行号
    console.log(colno)//发生错误的列号
    console.log(error)//Erroe对象
    
    return true//将代码错误定格在捕获阶段
}

window.addEventListener('error', (msg, url, row, col, error) => {
    console.log(
        msg, url, row, col, error
    );
    return true;
}, true);

注意vue

  • window.onerror只有在返回true时,异常才不会向上抛出,原理是冒泡机制。并且window.onerror是没法捕获到网络异常的,由于网络请求异常不会事件冒泡,虽然能在捕获阶段捕获到,可是没法判断HTTP的状态码,须要配合服务端才能排查。
  • 咱们平时写window.onerror的时候,最好写在最顶端,以避免前面的错误脚本阻断了。同时在vue或者react框架中,他们有自身的错误捕获机制,因此会掩盖window.onerror,好比vue的Vue.config.errorHandler。想详细了解看官网文档便可。
try...catch...finally
这种方式应该是咱们平时用的最多的,具体功能想必你们也应该都很清楚,将咱们须要检测的代码包裹在try和catch中,当发生语法错误或者其余错误时,就会从catch里捕获到,而无论前端发生了什么,最后finally里的代码总会执行。

下面的代码会怎么执行,你们能够思考一下java

try {
  try {
    throw new Error("oops");
  }
  catch (ex) {
    console.error("inner", ex.message);
    throw ex;
  }
  finally {
    console.log("finally");
    return;
  }
}
catch (ex) {
  console.error("outer", ex.message);
}

特别注意react

  • try...catch只能捕获到运行时的非异步错误,而语法错误和异步错误就捕捉不到。
  • 还有一点就是try..catch比较消耗性能,能少用的最好。
unhandledrejection
有些错误try..catch和windows.onerror也是无能为力的,好比说Promise实例从pending转变为rejected时,若是加了catch就会被捕获到,但要是没有加,那么继续抛出就会 Uncaught(in promise) Error

好比下面代码就捕获不到错误webpack

window.onerror = function(message, source, lineno, colno, error) { 
    console.log(message)//字符串错误信息
    console.log(source)//发生错误的脚本
    console.log(lineno)//发生错误的行号
    console.log(colno)//发生错误的列号
    console.log(error)//Erroe对象
    
    return true//将代码错误定格在捕获阶段
}

  // 调用Promise.reject类方法
    Promise.reject('promise error');
    // 在工厂方法中调用reject方法
    new Promise((resolve, reject) => {
        reject('promise error');
    });
    // 在工厂方法或then回调函数中抛异常
    new Promise((resolve) => {
        resolve();
    }).then(() => {
        throw 'promise error'
    });

咱们能够经过下面的方法监听到git

window.addEventListener('unhandledrejection', function (event) {
  // ...your code here to handle the unhandled rejection...

  // Prevent the default handling (such as outputting the
  // error to the console

  event.preventDefault();
});

可是这方法的兼容性有点失望
unhandledrejection.pnggithub

What the heck is "Script error"?
‘Script error’ 这个错误是比较常见的,通常经过windows.onerror捕获到后基本确实就是哪一个script文件有问题,并且这个文件仍是跨域的,既然是跨域致使信息不全,因此首先要解决的就是跨域问题,关于跨域方面的前端解决方案能够看我这篇文章《 前端常见跨域方案汇总
)》;

对于script标签,咱们还须要额外配置一个参数crossOriginweb

<script src='www.example.com' crossorigin></script>

至于服务端,经常使用的就是windows

了解sourceMap
对于这个功能的讲解,看阮大神的 讲解
)是最适合不过的了,固然了解其基本设计思路也是很重要的,SourceMap其实就是一个信息文件,存储着源文件的信息及源文件与处理后文件的映射关系。咱们平时vue或者react项目开发中,经过webpack配置在测试环境中默认开启生成SourceMap,出现错误可以及时重现原代码,可是正式环境咱们通常是不会将SourceMap文件发布上去的,可是正式环境的代码通常都是压缩过的,因此若是报错了,通常是很难 定位到原代码的位置,这时候优秀的错误上传功能,以及平台处理错误分析就显得尤其重要了。下图就是大概的设计思路。

sourcemap.png

Navigator.sendBeacon()存在的意义
平时咱们很常见网页卡顿或者直接崩溃,通常是经过window 对象的 load 和 beforeunload 事件实现了网页崩溃的监控;具体看这篇文章, Logging Information on Browser Crashes

实现代码跨域

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'));
   }

可是上面的编码模式存在不友好的问题,当咱们尝试在卸载页面前经过上传服务器数据,为了延迟页面卸载,须要经过同步XMLHttpRequest 发送数据或者建立一个几秒的循环来延迟卸载。这样的处理可想而知不是很友好,这时候sendBeacon()就横空出世了,很简单的实现向服务器发送数据,同时又不会影响下一个页面的加载,具体以下面简单的代码实现。

window.addEventListener('unload', logData, false);

function logData() {
    navigator.sendBeacon("www.youAddress.com", analyticsData);
}
扩展阅读

7 天打造前端性能监控系统

成熟解决方案
badjssentryraven-js
FunDebug
)

若是大神您想继续探讨或者学习更多知识,欢迎加入QQ或者微信一块儿探讨:854280588 QQ.png 微信
相关文章
相关标签/搜索