搭建前端监控,如何采集异常数据?( 二 )


// 响应拦截器instance.interceptors.response.use((response) => {return response.data;},(error) => {// 发生异常会走到这里if (error.response) {let response = error.response;if (response.status >= 400) {handleError(response);}} else {handleError(null);}return Promise.reject(error);},);
响应拦截器的第二个参数是在发生错误时执行的函数,参数就是异常 。我们首先要判断是否存在 error.,存在就说明接口有响应,也就是接口通了,但是返回错误;不存在则说明接口没通,请求一直挂起,多数是接口崩溃了 。
如果有响应,首先获取状态码,根据状态码来判断什么时候需要收集异常 。上面的判断方式简单粗暴,只要状态码大于 400 就视为一个异常,拿到响应数据,并执行上报逻辑 。
如果没有响应,可以看作是接口超时异常,调用异常处理函数时传一个 null 即可 。
前端异常
上面我们介绍了在 axios 拦截器中如何捕获接口异常,这部分我们再介绍如何捕获前端异常 。
前端代码捕获异常,最常用的方式就是用 try..catch.. 了,任意同步代码块都可以放到 try 块中,只要发生异常就会执行 catch:
try {// 任意同步代码} catch (err) {console.log(err);}
上面说“任意同步代码”而不是“任意代码”,主要是普通的写法 try..catch.. 是捕获不到的,只能用 .catch() 捕获,如:
try {Promise.reject(new Error('出错了')).catch((err) => console.log('1:', err));} catch (err) {console.log('2:', err);}
把这段代码丢进浏览器,打印结果是:
1: Error: 出错了
很明显只是 .catch 捕获到了异常 。不过与上面接口异常的逻辑一样,这种方式处理当前页面异常没什么问题,但从整个应用来看,这样捕获异常侵入性强,接入成本高,所以我们的思路依然是全局捕获 。
全局捕获 js 的异常也比较简单,用 .('error') 即可:
// js 错误捕获window.addEventListener('error', (error) => {// error 就是js的异常});
为啥不用 . ?
这里很多小伙伴有疑问,为什么不用 . 全局监听呢?.('error') 和 . 有什么区别呢?
首先这两个函数功能基本一致,都可以全局捕获 js 异常 。但是有一类异常叫做 资源加载异常,就是在代码中引用了不存在的图片,js,css 等静态资源导致的异常,比如:
const loadCss = ()=> {let link = document.createElement('link')link.type = 'text/css'link.rel = 'stylesheet'link.href = http://www.kingceram.com/post/'https://baidu.com/15.css'document.getElementsByTagName('head')[10].append(link)}render() {return