火影推荐程序连载16-聊聊前端监控——错误监控篇

当有人问起:你们的公司的这款应用用户体验怎么样呀?访问量怎么样?此时,你该怎么回答呢?你会回答:UV、PV 巴拉巴拉,秒开率、FP、TTI 巴拉巴拉。

那么,这些数据是哪里来的呢?显而易见,这些数据都来自前端监控系统。

前端监控的意义

当今时代,是一个快节奏的时代,应用的性能极大影响着用户的留存率,没有用户会忍受一个卡到爆的应用。而监控应用性能的重担,就由前端监控系统肩负着。

其次,对于线上应用来说,故障是不可避免的,对于高日活的应用来说,每次故障都意味着大量的损失。试想,如果是淘宝挂了一天,那么损失是多么惨痛。所以,对于开发人员来说,必须要尽早发现线上故障,而不是等到客户打爆客服的电话才发现。线上错误监控,也是前端监控的任务之一。

最后,作为商业公司,需要根据用户行为和数据进行分析,进一步制定各种策略,如果没有各种数据,那么 BI 会热情的找你谈谈人生。而这些数据,也是前端监控系统获取的。

总而言之,前端监控肩负着:性能监控、错误监控以及数据上报等功能,无论对于大公司还是小公司,可以说是必不可缺的了。

今天,我们先来聊聊前端监控中的错误监控。

错误监控概述

一般来说,按照错误监控错误监控可以分为:脚本错误监控、请求错误监控以及资源错误监控。

脚本错误监控

脚本错误大体可以分为两种:编译时错误以及运行时错误。其中,编译时错误一般在开发阶段就会发现,配合 lint 工具比如 eslint、tslint 等以及 git 提交插件比如 husky 等,基本可以保证线上代码不出现低级的编译时错误。大厂一般都有发布前置检测平台,能够在发布前提前发现编译时错误,当然,原理依然和之前所说的类似。

而发现并上报运行时错误就是前端检测平台的本质工作啦,一般来说,脚本错误监控指的就是运行时错误监控。

说到脚本错误监控,你想到的第一个是什么?对,就是 try catch !

在编写 JavaScript 时,我们为了防止出现错误阻塞程序,我们会通过 try catch 捕获错误,对于错误捕获,这是最简单也是最通用的方案。

但是,try catch 捕获错误是侵入式的,需要在开发代码时即提前进行处理,而作为一个监控系统,无法做到在所有可能产生错误的代码片段中都嵌入 try catch。所以,我们需要全局捕获脚本错误。

常规脚本错误

当页面出现脚本错误时,就会产生 onerror 事件,我们只需捕获该事件即可。

/**
 * @description window.onerror 全局捕获错误
 * @param event 错误信息,如果是
 * @param source 错误源文件URL
 * @param lineno 行号
 * @param colno 列号
 * @param error Error对象
 */
window.onerror = function (event, source, lineno, colno, error) {
  // 上报错误
  // 如果不想在控制台抛出错误,只需返回 true 即可
};

可以发现,各种错误监控所需的信息,如错误信息、错误源文件的 URL、错误行号、错误列号都被回调函数所传入。

但是,window.onload 有两个缺点:

  1. 只能绑定一个回调函数,如果想在不同文件中想绑定不同的回调函数,window.onload 显然无法完成;同时,不同回调函数直接容易造成互相覆盖。
  2. 回调函数的参数过于离散,使用不方便

所以,一般情况下,我们使用 addEventListener 来代替。

/**
 * @param event 事件名
 * @param function 回调函数
 * @param useCapture 回调函数是否在捕获阶段执行,默认是false,在冒泡阶段执行
 */
window.addEventListener('error', (event) => {
  // addEventListener 回调函数的离散参数全部聚合在 error 对象中
  // 上报错误
}, true)

tips:在一些特殊情况下,我们依然需要使用 window.onload。比如,不期望在控制台抛出错误时,因为只有 window.onload 才能阻止抛出错误到控制台

Promise 错误

使用了这两种方法,是不是可以捕获所有脚本错误了呢?这个问题再几年前其实是正确的,但是随着前端技术的发展,出现了 Promise 这项技术,而使用这两种常规方法无法捕获 Promise 错误。

和常规脚本错误的捕获一样,我们只需捕获 Promise 对应的错误事件即可。而 Promise 错误事件有两种,unhandledrejection 以及 rejectionhandled

当 Promise 被 reject 且没有 reject 处理器的时候,会触发 unhandledrejection 事件。

当 Promise 被 reject 且有 reject 处理器的时候,会触发 rejectionhandled 事件。

// unhandledrejection 推荐处理方案
window.addEventListener('unhandledrejection', (event) => {
  console.log(event)
}, true);

// unhandledrejection 备选处理方案
window.onunhandledrejection = function (error) {
  console.log(error)
}

// rejectionhandled 推荐处理方案
window.addEventListener('rejectionhandled', (event) => {
  console.log(event)
}, true);

// rejectionhandled 备选处理方案
window.onrejectionhandled = function (error) {
  console.log(error)
}

框架错误

由于我 React 使用的不多,所以在此只讨论下 Vue 的框架错误处理,如果有大佬了解 React 的框架错误处理,欢迎补充~

在 Vue 中,框架提供了 errorHandler 这个 API 来捕获并处理错误。

Vue.config.errorHandler = function (err, vm, info) {
  // handle error
  // `info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子
  // 只在 2.2.0+ 可用
}

值得一提的是,框架错误指的不是框架层面的错误,而是指框架提供了 API 来捕获全局错误。

请求错误监控

一般来说,前端请求有两种方案,使用 ajax 或者 fetch ,所以只需重写两种方法,进行代理,即可实现请求错误监控。

代理的核心在于使用 apply 重新执行原有方法,并且在执行原有方法之前进行监听操作。在请求错误监控中,我们关心三种错误事件:abort,error 以及 timeout,所以,只需在代理中对这三种事件进行统一处理即可。

tips:如果能够统一使用一种请求工具,如 axios 等,那么不需要重写 ajax 或者 fetch 只需在请求拦截器以及响应拦截器进行处理上报即可

资源错误监控

资源错误监控本质上和常规脚本错误监控一样,都是监控错误事件实现错误捕获。

那么如果区分脚本错误还是资源错误呢?我们可以通过 instanceof 区分,脚本错误参数对象 instanceof ErrorEvent,而资源错误的参数对象 instanceof Event

值得一提的是,由于 ErrorEvent 继承于 Event ,所以不管是脚本错误还是资源错误的参数对象,它们都 instanceof Event,所以,需要先判断脚本错误。

此外,两个参数对象之间有一些细微的不同,比如,脚本错误的参数对象中包含 message ,而资源错误没有,这些都可以作为判断资源错误或者脚本错误的依据。

/**
 * @param event 事件名
 * @param function 回调函数
 * @param useCapture 回调函数是否在捕获阶段执行,默认是false,在冒泡阶段执行
 */
window.addEventListener('error', (event) => {
  if (event instanceof ErrorEvent) {
    console.log('脚本错误')
  } else if (event instanceof Event) {
    console.log('资源错误')
  }
}, true);  眼看都到汽车销量旺季了,为了一年一次才会有的商机,众多车企都选择将旗下的车型在9月份推出市场。老张为大家介绍的起亚k50,领克06,宋plus这三款都是即将上市的新款车型,这三款车各自定位不同,能符合不同消费者的要求。
  
  出自i-gmp平台的全新起亚k5,最大的亮点就是车身尺寸有了大幅度的变化,新款k5的长宽高分别是4980×1860×1445毫米,轴距达到2900毫米。即便是最低配的起亚k5都配备了R17英寸的轮胎,从这种配置上能看出,起亚k5走的是运动化路线。
  
  新款起亚k5拥有1.5T\2.0T两款四缸发动机,匹配的变速箱包括7挡双离合和8挡手自一体,该车在混合工况下拥有5.6升油耗,符合国六排放要求。新款起亚k5最低配都支持定速巡航,后倒车雷达,后视镜加热,皮质方向盘,双温区自动空调,12.3英寸液晶显示屏等配置。
  
  领克06是在8月6日推出市场的,今天老张为大家介绍的领克06是2020款劲Pro版,这款车将在9月6日推出市场,该车的到来将进一步拉低领克06的准入门槛,毕竟这款车是最低配的车型。
  
  即将上市的领克06劲Pro版将搭载1.5T发动机,作为BMA架构下的小型SUV,最低配的车型依然拥有较高的颜值,在科技感和内饰的配置等方面,该车也有亮眼的表现。
  
  宋plus这款车也将在9月7日上市,这次上市的4款车型售价区间在11.88~14.68万,作为一款中型SUV,该车价格上的优势比较明显。宋plus这款车的外观延续比亚迪宋家族车型的设计语言,车头的辨识度还是比较高的。
  
  空间方面,宋plus的长宽高分别是4705×1890×1680毫米,轴距达到2765毫米,通过车身尺寸也能看出,宋plus是一款适合家用的大5座SUV。动力方面,比亚迪为这款车配备了1.5T发动机,匹配的变速箱为7速湿式双离合。
  
  台北“国史馆”数字典藏号:002-080200-00291-061。string e =www.qiaoheibpt.com "abc";
  
  //这里e还是使用字符串的留存性,且使用的还是a的地址。证明c分配的内存引用并没有放入常量池替换
  
  Assert.True(www.yachengyl.cn string.ReferenceEquals(www.letianhuanchao.cn a, e));
  
  Assert.False(www.feihongyul.cn string.ReferenceEquals(www.fengmingpt.com, e));
  
  string f www.baihuayl7.cn= "abc" + "abc";
  
  string g www.jintianxuesha.com= a +www.xinxingyulep.cn b;
  
  string h =www.jujinyule.com "abcabc";
  
  void testDeleteFileDir3(www.zhuyngyule.cn) throws IOException {
  
  Path path =www.baichuangyule.cn Paths.get(www.shentuylzc.cn"D:\\data\\test1");
  
  //如果文件不存在,返回false,表示删除失败(文件不存在)
  
  //如果文件夹里面包含文件,抛出DirectoryNotEmptyException
  
  void testDeleteFileDir4(www. jinmazx.cn) throws IOException {
  
  Path path = Paths.get(www.bhylzc.cn"D:\\data\\test1");
  
  boolean result = Files.deleteIfExists(path);
  
  System.out.println(result);
  
  //IsInterned 表示从常量池中获取对应的字符串,获取失败返回null
  
  //a+b实际上是发生了字符串组合运算,内部重新new了一个新的字符串,所以f,g引用地址不同
  
  Assert.False(string.ReferenceEquals(www.xinxingyulep.cn, g));
  
  Assert.True(string.ReferenceEquals(www.baihua178.cn string.IsInterned(www.lecaixuangj.cn), h));
  
  Assert.True(string.ReferenceEquals(www.yixinpt2.cn f,www.pinguo2yl.com h));
  
  总结:以上三款最有代表性的车型涵盖了小型SUV,中型SUV和B级车市场,这三款车都有出色的性价比,相信上市后会对竞争对手带来一定的生存压力,毕竟这三款车颜值高,动力表现不错。在这三款车型中最受关注的应该就是起亚K5了,因为这款车空间大、颜值高。

tips:使用 addEventListener 捕获资源错误时,一定要将 useCapture 即第三个选项设为 true,因为资源错误没有冒泡,所以只能在捕获阶段捕获。同理,由于 window.onerror 是通过在冒泡阶段捕获错误,所以无法捕获资源错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值