关于 JavaScript 错误捕获

腾讯云技术社区-掘金主页持续为你们呈现云计算技术文章,欢迎你们关注!javascript


做者:vienwuhtml

javascript的出错咱们应该都很熟悉,例如xxx undefined,SyntaxError等。java

咱们team将出现错误的javascript代码取名为badjs,也有一个开源的badjs项目,用于捕获和分析js错误,并提供了一些基础的报表数据分析。git

捕获错误通常有两种方式:

  • 使用window.onerror()捕获全局的js错误信息
  • 使用try{...}catch(e){...}包裹须要执行的代码,获取error对象的属性定位错误并上报

第一种方式最简单,但当执行的js代码和咱们的站点在不一样域即跨域时,因为浏览器的安全限制,onerror()方法只能捕获到一个固定的错误代码Script error.
具体可参考这里:点击查看github

咱们团队目前的业务基本都会将静态资源部署到cdn服务器,和站点处于不一样域,因此须要解决跨域问题。web

跨域问题能够经过服务器端设置access-control-allow-orgin:*解决,但并不完美。这个问题更深刻的信息能够参考这里:github.com/BetterJS/ba…ajax

第二种方式是手动包裹一些要检测的代码,没有跨域问题而且能够获取到err的对象的详细出错信息。
这种方式相对麻烦一些,但能够经过全局的hook,处理大部分状况,免除每次手动写try...catch的烦恼。正则表达式

咱们都知道js代码的执行是经过事件和定时器触发执行的,因此理论上将事件触发时的回调、定时器的回调包裹便可。api

咱们的badjs项目主要是经过第二种方式实现,并根据现有的业务,对如下几种方法进行了处理:跨域

  • define(),require()等方法
  • jQuery封装的一些事件,如$.event.add,$.event.remove,ajax等
  • setTimeout setInterval等

这里处理的原理比较简单,相似下面的代码:

function define(){
    ...
}
var a = define;
define = function(){
    try{
        a.apply(this,arguments);
    }catch(e){
        ...错误上报
    }
};复制代码

这里还有一些兼容性的问题须要处理,例如在ie低版本中setTimtout和setInterval方法并非function类型,而是object,因此没法使用改写function的方式进行包裹。相似的还有document.attachEvent方法也是object,不是function

除了对以上方法的单独处理外,还有一些意外状况没法处理,例如:

  • window.onload,Image.prototype.onerror等浏览器和dom的事件,这类方法没法直接改写function
  • 第三方的插件的自定义事件,如flash播放器提供的一些用于播放控制的事件。
  • 新的一些api,如FileReader.prototype.onload等

这些意外状况很难作全局的hook,因此只好手动try...catch。
咱们的badjs也提供了一个便捷的api,例如源代码是这样:

var img = new Image();
img.onload = function(){
    ...
};复制代码

使用tryjs包裹

var img = new Image();
img.onload = tryJs.spyCustom(function(){
    ...
});复制代码

除此以外,try...catch能获取的err对象在各不一样的浏览器之间,也有一些差别。好在有人已经作一个页面展现详细的差别,参考url: broofa.com/tests/Error…

一些其余的补充

回到捕获js错误这件事自己,是为了更好的监控并定位错误,帮助咱们改善代码质量,因此kael也提到另一个思路,能够灰度一部分用户,直接使用主域而不是cdn的js,直接避免跨域问题,这个思路也值得一试。

另外,错误上报数据和访问量等数据若是到结合一块儿分析,不只能够更快速的定位问题,甚至能够实现监控自动告警等,固然这个也很是复杂。

原文连接:ivweb.io/topic/55e3d…

相关推荐
移动端tryjs异常捕获
新用户850元大礼包,轻松上云
玩转JavaScript正则表达式


此文已由做者受权腾讯云技术社区发布,转载请注明文章出处
原文连接:www.qcloud.com/community/a…
获取更多腾讯海量技术实践干货,欢迎你们前往腾讯云技术社区