这种方案要求开发人员在编写代码的时候,在预估有异常发生的代码段使用try...catch
,在发生异常时将异常信息发送给接口:浏览器
可是 try-catch 处理异常的能力有限,只能捕获捉到运行时非异步错误,对于语法错误和异步错误就显得无能为力,捕捉不到。网络
try{ //可能发生异常的代码段 }catch(e){ //将异常信息发送服务端 }
try...catch
的优势是能够细化到每一个代码块,而且能够自定义错误信息以便统计。异步
具体到上文提到的两种js异常,try...catch
没法捕获语法错误,当遇到语法错误时,浏览器仍然会抛出错误Uncaught SyntaxError
,可是不会被捕获,不会走进catch的代码块内。函数
另外,若是try代码块中有回调函数也不会被捕获,好比:工具
try{ var btn = $('#btn'); btn.on('click',function(){ //throw error }); }catch(e){}
上述代码中btn的监听函数里抛出的异常没法被外层的catch捕获到,必须额外套一层:spa
try{ var btn = $('#btn'); btn.on('click',function(){ try{ //throw error }catch(e){} }); }catch(e){}
综上所述,try...catch
方案的部署很是复杂,若是人工部署除了要求巨量的工做量,还跟开发人员的能力和经验有关。若是依赖编译工具部署(好比fis),那每一个代码块都套一层try...catch
也是很是难看的而且容易引起一些不可预估的问题。日志
window.onerror 捕获异常能力比 try-catch 稍微强点,不管是异步仍是非异步错误,onerror 都能捕获到运行时错误。code
这种方式不须要开发人员在代码中书写大量的try...catch
,经过给window添加onerror监听,在js发生异常的时候即可以捕获到错误信息,语法异常和运行异常都可被捕获到。blog
可是window.onerror
这个监听必须放在全部js文件以前才能够保证可以捕获到全部的异常信息。接口
window.onerror 函数只有在返回 true 的时候,异常才不会向上抛出,不然即便是知道异常的发生控制台仍是会显示 Uncaught Error: xxxxx。
对于 onerror 这种全局捕获,最好写在全部 JS 脚本的前面,由于你没法保证你写的代码是否出错,若是写在后面,一旦发生错误的话是不会被 onerror 捕获到的。
另外 onerror 是没法捕获到网络异常的错误。
window.onerror
事件的详细信息参考这里。
/** * @param {String} errorMessage 错误信息 * @param {String} scriptURL 出错文件的URL * @param {Long} lineNumber 出错代码的行号 * @param {Long} columnNumber 出错代码的列号 * @param {Object} errorObj 错误信息Object */ window.onerror = function(errorMessage, scriptURL, lineNumber,columnNumber,errorObj) { // code.. }
下图是被onerror捕获到的一个异常的具体信息:
综上所述,window.onerror
方案的优势是减小了开发人员的工做量,部署方便,而且能够捕获语法错误和运行错误。
缺点是错误信息不能自定义,而且errorObj每种浏览器的实现有略微差别,致使需统计的信息有局限性。