关于javascript错误捕获

```

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

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


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

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


第一种方式最简单,但当执行的js代码和我们的站点在不同域即跨域时,由于浏览器的安全限制,onerror()方法只能捕获到一个固定的错误代码`Script error.`。
具体可参考这里:[点击查看](http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#runtime-script-errors)

我们团队目前的业务基本都会将静态资源部署到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,直接避免跨域问题,这个思路也值得一试。

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

10 个技巧促使你的 Git 的技能上一个台阶——SitePoint

第一时间关注程序猿(媛)身边的故事 最近,我们发布了一些教程促使你了解 Git 基础知识和在团队环境中使用 Git。谈论的指令已经足够帮助一个开发者在 Git ...

1798
来自专栏达摩兵的技术空间

前端文件下载通识篇

前端如何实现下载文件呢?随着前端技术的发展,越来越多的前端需求中会出现下载文件这样的需求。

2092
来自专栏地方网络工作室的专栏

打造前端MAC工作站(五)让我们熟悉一下 MAC 命令行吧!

打造前端MAC工作站(五)让我们熟悉一下 MAC 命令行吧! 前言 对于初次基础mac或者linux的朋友来说,接收和使用命令行是一个比较困难的事情。但是,正如...

22010
来自专栏漏斗社区

工具|nessus自定义扫描策略

我们是谁? nessus工具! 我们要做什么? 扫描漏洞! 什么时候扫? 天天扫! 序言 有些时候我们并不希望进行全面的扫描和检测,仅需要针对某些漏洞进行安全...

4986
来自专栏EAWorld

8种至关重要OAuth API授权流与能力

在本文中,Curity的Daniel Lindau概述了重要的OAuth授权流程和能力。

451
来自专栏IT技术精选文摘

分布式存储理论与实践初探 (二)

数据分布 分布式存储系统需要将数据分布到多个节点,并在多个节点之间实现负载均衡。常见的数据分布的方式有两种:一种是哈希分布,如一致性哈希,典型的系统是Amazo...

2136
来自专栏陈树义

Java并发编程:进程和线程之由来

Java多线程基础:进程和线程之由来   在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程。当然,Java并发编程涉及...

3514
来自专栏Java进阶架构师

「架构技术专题」构建网站高可用架构(详细分析篇)(6)

可用性指标时网站架构设计的重要指标,对外是服务承诺,对内是考核指标,具体到每个工程师,更多的是使用故障分。

663
来自专栏ImportSource

Gitlab.com宕机始末

接上集:Gitlab.com误删数据最近动态:恢复60% 14小时前 数据库恢复60%; 13小时前 gitlab在国外某非著名视频网站直播自己的数据库恢复进...

3896
来自专栏知晓程序

电商/票务类小程序必读,如何用小程序推送消息?

通常,服务方向用户推送的消息都带有通知性质,文案也相对固定。服务方将这类固定的文案制作成模板,这些文案就可以快速重复使用。

1012

扫码关注云+社区