前言
开发者有时会面临上线的生产环境包出现了异常??? ,在长期生产bug并修复bug的循环中总结出一下几个痛点:
-
无法快速定位到发生错误的代码位置,因为脚手架构建时会用webapck自动帮我们压缩代码,而上线版本又通常不会保留
source map
(开源贡献者除外) -
无法第一时间通知开发人员异常发生
-
不知道用户OS与浏览器版本、请求参数(如页面ID);而对于页面逻辑是否错误问题,通常除了用户OS与浏览器版本外,需要的是报错的堆栈信息及具体报错位置。
错误埋点追踪系统的出现就是为了应对上述问题的解决方案,笔者正好最近接触了不少前端埋点与错误处理的博客内容,按例阶段性产出博客总结一下。
什么是埋点
还不了解的同学可以阅读以下文章:
前端-埋点-理念-通识-浅谈
大数据时代数据的重要性不言而喻,而其中最重要的就是用户信息的采集。埋点,无论是项目后期的复盘,还是明确业务价值,还是产品价值的挖掘,都具备很重要的意义。
前端异常捕获
在ES3之前js代码执行的过程中,一旦出现错误,整个js代码都会停止执行,这样就显的代码非常的不健壮。从ES3开始,js也提供了类似的异常处理机制,从而让js代码变的更健壮,程序执行的过程中出现了异常,也可以让程序具有了一部分的异常恢复能力。js异常的特点是,出现不会导致JS引擎崩溃,最多只会终止当前执行的任务。
回归正题,我们该如何在程序异常发生时捕捉并进行对应的处理呢?在Javascript中,我们通常有以下两种异常捕获机制。
基本的try…catch语句
function errFunc() {
// eslint-disable-next-line no-undef
error;
}
function catchError() {
try {
this.errFunc();
} catch (error) {
console.log(error);
}
}
catchError()
复制代码
能捕捉到的异常,必须是线程执行已经进入 try catch 但 try catch 未执行完的时候抛出来的,以下都是无法被捕获到的情形。
-
异步任务抛出的异常(执行时try catch已经从执行完了)
-
promise(异常内部捕获到了,并未往上抛异常,使用catch处理)
-
语法错误(代码运行前,在编译时就检查出来了的错误)
-
优点:能够较好地进行异常捕获,不至于使得页面由于一处错误挂掉
-
缺点:显得过于臃肿,大多代码使用
try ... catch
包裹,影响代码可读性。
面试官:请用一句话描述 try catch 能捕获到哪些 JS 异常
全局异常监听window.onerror
window.onerror
最大的好处就是同步任务、异步任务都可捕获,可以得到具体的异常信息、异常文件的URL、异常的行号与列号及异常的堆栈信息,再捕获异常后,统一上报至我们的日志服务器,而且可以全局监听,代码看起来也简洁很多。
- 缺点:
-
此方法有一定的浏览器兼容性
-
跨域脚本无法准确捕获异常,跨域之后
window.onerror
捕获不到正确的异常信息,而是统一返回一个Script error
,可通过在<script>
使用crossorigin
属性来规避这个问题
image.png
window.addEventListener(‘error’, function() {