likes
comments
collection
share

3步让你理解错误监控功能

作者站长头像
站长
· 阅读数 20

这几天在回顾自己之前做过的一些工具项目,有一个比较实用的错误监控功能引起了我的兴趣,因此我想把这个功能拿出来写一篇文章。

首先我要讲一个比较有趣的故事。

2年前的某天,生产环境的某个页面崩溃了,因为当时在忙另外一个项目,没有花时间注意这边,一周之后才从某个同事那里得知代码报错,页面访问不了啦。

这件事情给了我很大的打击,让我很羞愧,于是我打算自己做一个错误监控的功能,并能及时的提醒我,让我有时间做出调整。

接下来,就说说我的这个错误监控功能是如何实现的吧。

首先,我想问大家一个问题,你们知道有多少种方式可以捕捉到代码异常吗?

我给大家1分钟的时间思考。

......

我在下面文章部分将会给大家公布答案。

这篇文章我将分成下面几部分跟大家一一分解。

一、捕捉错误的几种方式
    1try catch
    2window.onerror
    3window.addEventListener('unhandledrejection', fn)
    4window.addEventListener('error',fn)
二、如何集成给不同项目使用
三、如何发qq邮件
四、其他几种错误抓取的处理
五、总结

捕捉错误的几种方式

1、try catch

这种捕捉错误的方式应该是很多朋友第一时间能想到的对吧。

比如我们在写一些同步代码的时候就可以通过try catch的方式捕获到,例如下面的例子:

try {
  console.log(a);
} catch (error) {
  console.log(error);
}

此时error获取到的是a is not defined,也就是a没有定义的意思,并且显示了具体的行数,如下所示: 3步让你理解错误监控功能

如果代码中出现这种错误,就可以通过try catch的方式捕捉到错误,并上报给服务器保存了。

但是,我发现try catch是没办法捕捉到异步任务的,例如下面的例子:

try {
  setTimeout(() => {
    console.log(a);
  })
} catch (error) {
  console.log(error);
}

我们发现try catch这种情况下的错误不能捕获到,而是代码直接爆红,抛出错误:a is not defined。如下图所示:

3步让你理解错误监控功能

于是,我们就有了第二种捕捉错误的方式。

2、window.onerror

上面说到了try catch不能捕获到异步任务,那我接下来给大家提供一个可以解决这个问题的方法,叫做:window.onerror,代码如下:

setTimeout(() => {
  console.log(error);
})
window.onerror = function(msg, url, row, col, error){
  console.log(error);
  // 返回true目的是不让页面报红
  return true;
}

此时捕获到了错误信息,并且能拿到错误的文件和对应的行数,如下所示:

3步让你理解错误监控功能

我们常见的异步,还有一种是Promise的异步,那Promise的异步错误,我们试试window.onerror是不是也能捕捉到呢?

代码如下:

Promise.reject('第一个错误');
window.onerror = function(msg, url, row, col, error){
  console.log(error);
  return true;
}

直接抛红了,如图所示: 3步让你理解错误监控功能

看来还是要找其他方法解决。

3、window.addEventListener('unhandledrejection', fn)

上面说到window.onerror也不能捕获到Promise的错误,于是我们又找了一种方法来捕捉到这种错误,那就是window.addEventListener。我们写个例子试一下效果:

Promise.reject('第一个错误');
window.addEventListener('unhandledrejection', e => {
  // 阻止默认事件
  e.preventDefault();
  console.log('Promise抛出的错误异常', e.reason);
  return true;
})

查看打印的结果: 3步让你理解错误监控功能

所以这种错误,我们也能捕捉到了。

接下来还有一种错误是,文件找不到的错误。比如你的图片在cdn上放的好好的,结果某一天同事把你的图片删掉了,然后这个图片就找不到了,这种情况也要捕捉到并通知到相关人员(我们要使用技术,不能做无辜的背锅侠啊😂)

那么,这种情况怎么捕获呢?

4、window.addEventListener('error',fn)

上面说到文件找不到的情况,在js中怎么捕捉到你的错误。下面,我们写一个例子,看是否能捕获到这个问题。

<div class="root" id="root">
  <img src="./hello.png" alt="这是引入的图片" />
</div>
<script>
// 捕捉文件丢失的错误
window.addEventListener('error', (msg, url, row, col, error) => {
  console.log('文件丢失的错误', error);
  return true;
}, true)

</script>

下面看执行文件之后,打印的结果:

3步让你理解错误监控功能

以上,就是捕捉错误的4种方式。我们在上面四种情况下获取到错误之后,就可以调用一个上报接口将数据提交到服务端。

服务端通过对不同的错误等级和业务做不同的处理,比如非常严重的可以自动拨打电话给相关开发人员;稍微轻微的可以发送邮件到邮箱等等。

二、如何集成给不同项目使用

  • 1、可以将以上四种错误的捕捉集成一个report-error.min.js的文件,并上传到cdn中。
  • 2、在捕捉到错误的时候即调用上传错误的ajax方法,将错误上报到服务端。
  • 3、将需要上报错误监控的项目在全局引入report-error.min.js文件,即可实现自动上报。
  • 4、获取到错误信息,设计一个后端管理对这些错误进行分析和管控。

三、如何发qq邮件

我当时是引用了一个nodemailer的npm包,实现了发qq邮件的功能,非常好用。

以下是nodemailer的官网,多看两边就能懂了。

四、其他几种错误的抓取

1. 微信网页是否被封

之前在做一些营销页的时候,要投放比较多的微信宣传页进行引流,经常有一些竞争对手或者用户会主动点击页面的投诉,然后一些页面运营了十几天之后可能直接被微信封掉了;这时候需要尽快的更换能使用的宣传页,避免流量丢失。

后面我就把这部分功能放入到了错误监控系统中,将需要监控的页面放入到监控列表中,每隔10min去动态的轮询一次,等到页面被微信封了之后10min内,即会发邮件通知相关人员进行替换。他的具体实现逻辑如下: 首先通过微信自带的https://api.weixin.qq.com/cgi-bin/shorturl?access_token+${token}这个将目标链接生成一个短链接,然后主动模拟浏览器访问这个短链接,如果返回的结果包含weixin110.qq.com,则表示被封号了;否则,页面正常运行着。

2. 监控网页是否挂掉了

上一家公司服务器是部署在院内的,而不是用的云服务器。运维人员在给服务器插拔线、或者部署其他院内系统的时候,常常会影响到目前线上在使用的功能,因此我在后台做了一个定时任务轮询,将几个关键项目首页添加到访问列表中,即可以定时的探测到是否因为运维的原因服务被停了。如果服务停了,则邮件通知相关人员重启服务。

五、总结

最后总结一下,其实错误监控最重要的就是把各种错误的情况都捕捉到,捕捉到之后调用上报接口到服务器,根据业务关系和错误严重程度做一些通知。然后如果想对错误做进一步分析,可以做一个管理后台单独把错误数据拎出来统计。

如果这篇文档对你有帮助,欢迎点赞、关注或者在评论区留言,我会第一时间对你的认可进行回应。精彩内容在后面,防止跑丢,友友们可以先关注我,每一篇文章都能及时通知不会遗失。