关于 javascript 错误捕获

作者:vienwu

  • 随便写点啥,不然要被k。。

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

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

捕获错误一般有两种方式:

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

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

我们团队目前的业务基本都会将静态资源部署到cdn服务器,和站点处于不同域,所以需要解决跨域问题。

跨域问题可以通过服务器端设置access-control-allow-orgin:*解决,但并不完美。这个问题更深入的信息可以参考这里:https://github.com/BetterJS/badjs-report/issues/3

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

我们都知道js代码的执行是通过事件和定时器触发执行的,所以理论上将事件触发时的回调、定时器的回调包裹即可。

我们的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: http://broofa.com/tests/ErrorProperties.htm。

一些其他的补充

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

另外,错误上报数据和访问量等数据如果到结合一起分析,不仅可以更快速的定位问题,甚至可以实现监控自动告警等,当然这个也非常复杂。

原文链接:http://ivweb.io/topic/55e3d6e3771670e207a16bd5

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

前端性能优化——桌面浏览器前端优化策略

作者:ouven https://my.oschina.net/zhangstephen/blog/1601382 摘要: 前端性能优化是一个很宽泛的概念,本书...

1976
来自专栏开源优测

AutoLine源码分析之如何构建restful API

在autoline开源平台中我们采用了blueprint来统计管理路由,使用flask-restful插件来实现restful API

902
来自专栏Angular&服务

Angular2 @Component

它的配置更简单一些,非常适合组件化的app架构。使用web组件和使用Angular风格的app架构使得编写app更为简便。

572
来自专栏小程序的道路

小程序生命周期

小程序并不是 HTML5 应用,而是更偏向于传统的 CS 架构,它是基于数据驱动的模式,一切皆组件(视图组件)。下面是小程序与普通 Web App 的对比。 ...

1021
来自专栏杨龙飞前端

chrome cpu占用100%

1414
来自专栏ppjun专栏

Vue 入门之网络请求

Vue 2.0 之后官方推荐使用 axios 来完成前端的网络请求,不再推荐使用 vue-resource 了。下面我们安装使用 axios,来完成的常见的 g...

722
来自专栏hbbliyong

web跨域解决方案

阅读目录 什么是跨域 常用的几种跨域处理方法: 跨域的原理解析及实现方法 总结 摘要:跨域问题,无论是面试还是平时的工作中,都会遇到,本文总结处理跨域问题的几种...

69210
来自专栏JetpropelledSnake

Web前端学习笔记之前端跨域知识总结

相信每一个前端er对于跨域这两个字都不会陌生,在实际项目中应用也是比较多的。但跨域方法的多种多样实在让人目不暇接。老规矩,碰到这种情况,就只能自己总结一篇博客,...

593
来自专栏快乐八哥

HTML5 Video Player概览

从以下三个方面分析 1.浏览器和设备的市场份额 2.媒体格式的支持 通过服务器端detect浏览器发送请求时的user-agent。 ? 3.标签属性 属性支持...

1756
来自专栏everhad

简易搜索功能小记

简易搜索功能小记 自从上个版本软件中加入了列表的搜索功能,现在是个列表的地方产品都要给提供搜索。 @_@ 类似联系人、短信或者文件等的集合数据,用户输入关键字,...

1940

扫码关注云+社区