移动Web开发过程中,在真机测试时,往往会遇到一些PC调试无法重现的问题,这时候我们需要在手机上拦截错误,并有相应的输出。公司和网上都有类似的工具/类库,但如果纯粹一个简单的调试,或许不需要引入工具或类库,我们只需要知道全局拦截的原理。
其实很简单,就是window.onerror
语法:
实例:
下面的例子展示如何使用 onerror 事件来捕获错误:
另外,如果我们想在chrome控制台中直接模拟这个过程,会发现,直接使用throw new Error,无法触发这个onerror,这个可能是因为控制台的环境跟页面环境不一样。
但换一个方式,就可以触发了:
其实很简单,就是window.onerror
语法:
οnerrοr=handleErr
function handleErr(msg,url,l)
{
//Handle the error here
return true or false
}
浏览器是否显示标准的错误消息,取决于 onerror 的返回值。如果返回值为 false,则在控制台 (JavaScript console) 中显示错误消息。反之则不会。
实例:
下面的例子展示如何使用 onerror 事件来捕获错误:
<html>
<head>
<script type="text/javascript">
οnerrοr=handleErr
var txt=""
function handleErr(msg,url,l)
{
txt="There was an error on this page.\n\n"
txt+="Error: " + msg + "\n"
txt+="URL: " + url + "\n"
txt+="Line: " + l + "\n\n"
txt+="Click OK to continue.\n\n"
alert(txt)
return true
}
function message()
{
adddlert("Welcome guest!")
}
</script>
</head>
<body>
<input type="button" value="View message" οnclick="message()" />
</body>
</html>
另外,如果我们想在chrome控制台中直接模拟这个过程,会发现,直接使用throw new Error,无法触发这个onerror,这个可能是因为控制台的环境跟页面环境不一样。
但换一个方式,就可以触发了:
setTimeout(function(){throw new Error}, 1000)
而实际上要做好bug监控,单单onerror是不够的。
兼容浏览器坑在哪里?
- Error对象的属性各有不同,例如大名鼎鼎的Chrome的Error对象木有fileName,lineNumber以及columnNumber属性;
- Onerror事件的参数各有不同,例如老版本的Firefox木有columnNumber 和error参数
- API不同,例如老版本的IE木有JSON对象;
- 同一个属性名在不同浏览器的含义不同;
- 同一个属性在不同浏览器的名称不同;
- 国内浏览器的IE兼容模式与真正的IE也略有不同;
- ……
这些问题大概前端工程师都会深有同感吧。
错误智能聚合
同样的代码产生的同一个错误,在不同浏览器上的报错信息是各不相同的。name不同的错误可能是同一个错误,例如SyntaxError与ReferenceError;message不同的错误可能是同一个错误,例如can not find variable fundebug与fundebug is not defined。并且,同一个错误在不同浏览器下的lineNumber,columnNumber,stack,与url都有可能不同。
对于这个问题,我们对收集的错误利用机器学习算法进行了智能聚合,尽量将同一个错误聚合到一起,减少重复报警。根据我们的初步估算,目前聚合算法能够将90%的重复错误成功聚合,这样极大地提高了用户分析错误的效率。
Fundebug是前端JavaScript错误实时监控平台,经过大量兼容性调试,Fundebug的JavaScript监控插件已经能够在各种主流浏览器中自动捕获错误,并且可以获取最全面的错误信息,帮助开发者更快的Debug。