关于小组页面脚本错误捕获
平时本地或者测试环境开发,我们都能在调试面板之类的很直观看到脚本错误,出什么错,在哪,错误定位,一目了然,还能断点调试,这部分错误,一般会在开发以及QA测试阶段,就能大部分发现与修复。但是,如何捕获发现线上用户的错误呢?用户的网络、浏览器、电脑、手机等千奇百怪,总不能每次都远程用户电脑看一下它的Chrome吧?
一、如何捕获错误?
1、全局方式
window.onerror函数,可以捕获追踪全局的脚本错误,只要报错了,就会调用此函数,函数具体使用参数如下:
window.onerror = function(msg,url,line,col,errorObj){
console.log(msg); //错误的具体信息,字符串来,提示错误的具体内容(并没有错误堆栈)
console.log(url); //错误的脚本文件地址,字符串,提示发生错误的具体文件
console.log(line); //错误的行数
console.log(col); //错误的列数,注意低版本IE是没有此参数
console.log(errorObj); //错误信息的对象,保存着错误的堆栈和详情,低版本IE也没有此参数
}
从上面参数来看,几乎能满足我们的需要了,只要统一每个页面都引用这段代码,就能监控用户的错误了,那实际用起来的时候,会有什么问题和限制呢?是不是真那么好用?
基于安全考虑,
webkit
内核的,只会显示同源的脚本错误信息,外域的,统一提示Script Error
,然后第0行
错误,当然这个是有办法解决,给script
添加属性crossorigin
,以及服务器需要返回头部Access-Control-Allow-Origin:*
,这样就能显示完整的错误信息了测试发现,会上报很多莫名其妙的错误上来,而对应的错误文件地址,跟我们完全没有关系。
window.onerror
会捕获页面所有的错误,包括浏览器第三方插件
、页面被劫持塞进去的脚本
、浏览器本身错误
等等,然而这些我们是没法修复。大部分情况下,我们只能获取到错误的信息和行数,没有堆栈信息,比如:
a is Undefined
,错误文件是:jquery.js
,行数是第1行
;懵圈了,我想应该不是jquery
的问题,是我们代码调用了jquery
方法,但出错了,结果,这个错误上报了,等于没上报,也不知道哪有问题。
基于上面考虑,这种方式一般不采用(一开始是使用,后来放弃了)。
2、局部方式
try-catch模式,可以捕获包裹在try内的函数错误,报错了,就会调用catch回调:
try{
//do something
}
catch(e){
console.log(e); //错误信息对象,包含堆栈信息
}
try-catch
对比起window.onerror
,兼容性更强,而且不存在同源跨域问题,错误捕获的信息更加全,定位错误会更加容易些,也不会上报一些乱七八糟的内容,不过使用有一些局限性:
- 需要针对每个需要的地方用
try-catch
包裹起来,写多了,就烦,改起来也头疼 - 异步回调和事件代理,是捕获不了错误,例如下面这种:
try{
setTimeout(function(){
//do something
},1000);
}
catch(e){}
即使setTimeout
中代码出错了,依然catch不到错误
try{
$("#btn").on("click",function(){
//do something
});
}
catch(e){}
跟上面一样,点击了按钮,出错了,也捕获不到,除非你的try-catch
是包裹do something
回调函数内,所以不能直接用一个try-catch
包裹住整个js文件代码
二、选择与改进
基于同源以及错误信息的精确详细等情况,最终选择了try-catch方式来做错误捕获
1、将try-catch集成到AMD或者CMD的模块中
nie.define = function(name,cb){
try{
cb();
}
catch(e){}
}
比如上面这样,在定义模块的函数中插入,这样写代码时候,就不用去刻意写try-catch
了,但需要推进大家使用模块化开发,也有利于大家的模块化思维。
2、重写常用回调与代理函数
异步回调,以及代理事件,即使用了上面的方式,也依然捕获不了错误,所以,唯一办法就重写他们,然后捕获回调
- 重写了JS原生的函数,比如:
setTimeout
、setInterval
、addEventListener
等方法 - 重写了组内常用的
jQuery
库的函数,比如:$.bind
、$.on
、$.ajax
等
这样能满足大部分的场景需求了
3、错误上报
使用开源的错误统计系统,来做统计查询与邮件发送等事情
三、后记
错误统计,能主动发现线上用户的错误,以及项目上线后的一些情况,错误系统会后续开放给大家,目前还存在一些小问题。
手机阅读请扫描下方二维码:
12345678
1
555
1
555
555
1
555
1
1
1
1
1
1
1
1
1
1
1
1
12345678
555
civeulcxlnoujbbsjrpr
12345678
12345678
12345678
12345678
12345678
1
1
1
1
1
555
1
1
555
1
1
1
1
555
1
1
1
1
1
1
555
1
1
555
1
555
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1