前端错误信息捕获探索

166 阅读3分钟

「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战

前言

最近一段时间,公司内部开始搭建属于自己的日志监控平台,很遗憾,我没有机会参与其中。但是,我是一个耐不住寂寞的程序猿啊,即使没有参与到其中,但是不影响我也进行一番探索。这不,关于报错信息捕获的探索就给提上日程了么。

错误类型

在进行完整错误信息捕获之前,需要先了解错误类型都有哪些。只有了解了所有的错误类型,才能准确的捕获到项目中的代码错误。

语法错误

这种错误大多数时候,是由于开发过程中代码失误或者没有进行一些边界情况处理,导致的代码运行报错。这类错误是日常开发中最常见,也是最容易疏忽的错误类型

如果大家想要了解更多的语法错误,可以通过是 『传送门』 进行了解。

逻辑错误

这种错误是开发过程中比较常见的一种错误类型,代码本身没有错误,只是执行结果跟预期不符。但是这种错误无法通过单纯的错误信息捕获的方式来处理,只能通过逻辑梳理来逐步排查。

资源加载错误

由于网络原因或者服务端资源移除等各种各样的原因导致的资源加载失败而产生的错误类型。

错误捕获

try catch

这是最常见的一种错误信息捕获,只需要将需要执行的代码块放到try中即可。如果发生错误,就会将信息传入到catch中捕获。

但是,这种方式可以进行具体实际开发的时候使用,不太适合进行数据埋点的时候进行数据获取。而且,有一点需要特殊注意,一旦通过这种方式处理的话,那么就没有通过其它方式进行错误信息的二次捕获。

    try {
      let a;
      
      console.log(a.name);
    } catch (error) {
      console.log('error is :', error);
    }

特别说明

关于使用try catch进行错误信息捕获,需要特别说明一点,对于setTimeout和setInterval这类代码块中的语法错误是无法捕获的。

window.onerror

上帝关上了一扇门,又会打开一扇窗户。除了通过try catch的方式捕获错误外,我们还有另外的方式:window.onerror。

    window.onerror = function (msg, url, lineNo, columnNo, error) {
        var string = msg.toLowerCase();
        var substring = "script error";
        
        if (string.indexOf(substring) > -1){
            ...
        }
        
        return false;
    };

这样的话,错误就会抛出到error事件中来,即使是setTimeout和setInterval中的语法错误也能捕获到。

但是,对于语法错误和大多数异步任务是无法通过这种方式捕获的

window.addEventListener('error')

这种方式可以捕获的错误类型与window.onerror基本差不多。唯一的区别是:window.addEventListener可以捕获资源加载的错误。

    window.addEventListener('error', (err) => {
        ...
    });

但是,还是有问题,对于Promise中的报错,除了then的方式,我们还是没有办法捕获到。

window.addEventListener('unhandledrejection')

其实,js机制本身为我们提供了一种方式:unhandledrejection监听事件。当promise执行报错,没有被catch捕获的时候,会抛出unhandledrejection错误被捕获到。

    window.addEventListener('unhandledrejection', (err) => {
        ...
    });

结尾

到这里,其实大多数报错信息我们都可以捕获到了,接下来其实就可以进行sdk封装,然后进行错误上报了。

欢迎小伙伴在下方评论区进行留言交流。