浅谈前端常见监控错误类型、错误收集

824 阅读3分钟

最近在研究前端监控相关的内容,整理下前端相关的错误,记录下

一、常见的前端异常

  • 语法错误,编译阶段就可以发现的错误
  • JS运行异常,属性、方法缺失,浏览器不支持等
  • 加载静态资源错误
  • 请求接口异常:Ajax、Fetch、websocket
  • Promise处理错误
  • 框架错误:React、Vue、Angular
  • 获取压缩、混淆后的代码错误

二、监控流程

graph TD
监控错误:JsError/Promise --> 收集错误:整理错误信息数据结构 --> 上报错误:上传错误信息到数据库,控制重复上传频率 --> 分析错误:错误类型,错误出现的频率 --> 错误报警:推送邮件/短信/微信/语音等 --> 定位错误:错误发生的代码位置 --> 解决错误:配置错误处理人等信息

三、JS错误

类型含义说明
Error错误基类new Error(),有两个属性name和message,name错误类型、message错误信息
SyntaxError语法错误语法错误
ReferenceError引用错误常见于引用了一个不存在的变量: let a = undefinedVariable;
RangeError有效范围错误数值变量或参数超出了其有效范围。 常见于 1.创建一个负长度数组 2.Number对象的方法参数超出范围:let b = new Array(-1)
TypeError类型错误常见于变量或参数不属于有效类型 let foo = 3;foo();
URIErrorURL处理函数错误使用全局URL处理函数错误,比如 decodeURIComponent('%');
EvalErrorEval错误常常出现在TypeError

1、Error

new Error("test")

image.png

Error的属性:name, message。

2、SyntaxError

语法错误:该错误在编译阶段就可以发现

// console.log少了一个小括号,代码编译出现语法错误
console.log(testFinally()

image.png

该错误可以在编译阶段抛出,所以不做监控

3、ReferenceError

引用错误:当使用未定义的变量时,就会抛出该错误,该错误大多数在编译阶段就可以检测出来。

image.png

4、TypeError

类型错误:值类型非预期的错误。该错误类型是监控中出现的大头,如接口返回数据,值为undefined

// data 来自接口返回,值为undefined或null,而undefined和null没有length属性
data.length
console.lg("this is a TypeError")

image.png

自行定义TypeError类型错误:自行定义一些类型导致的错误

function add(a, b) {
    if(typeof a !== 'number'){
        throw TypeError(`The first argument must be a number`)
    }
    if(typeof b !== 'number'){
        throw TypeError(`The second argument must be a number`)
    }
    return a + b
} 

add('string', 1);

image.png

5、RangeError

数组长度错误:当数组的长度超过计算机允许的最大值、小于数组长度的最小值,就会出现该错误

image.png

6、URIError

URL解析或编码错误:

  • encodeURI
  • decodeURI
  • decodeURIComponent
  • encodeURIComponent

image.png

7、EvalError

EvalError该类错误常常表现为TypeError,如下图

let e = new eval();

image.png

8、自定义Error类

可以在Error类型的基础上扩展错误类型,自定义类型

class InvalidCallError extends Error {
    name: "InvalidCallError",
    constructor(message){
        super()
        this.message = message
    }
}

const error = new InvalidCallError("this is a InvalidCallError")

四、获取资源加载错误

资源错误指:js、图片、css等静态资源加载异常

例如:有一个不存在的图片路径404了。我们依然可以监听该错误,通过error,target字段判断是否为资源类型

<img src="http://localhost:9000/index.png" />

window.addEventListener('error', function(event) { 
    console.log("addEventListener", event)
}, true)

image.png

五、Promise异常

Promise相关的错误作为一个单独的错误类型,可以获取对应的错误信息

Promise.reject("test")

window.addEventListener('unhandledrejection', function(event) { 
    console.log("unhandledrejection", event)
}, true)

image.png

六、React错误捕获

React暴露了方法来监听错误,封装如下高阶组件,在componentDidCatch中处理捕获的错误

import * as React from 'react'; 

class ErrorListening extends React.Component { 
    constructor(props) { 
        super(props); 
    }
    componentDidCatch(error, info) { 
        console.log("error", error)
    }   
}

在项目中使用

import React from "react"; 

<ErrorListening> 
    <App /> 
</ErrorListening>

七、监听前端报错信息

1、window.onerror

window.onerror = function(message, source, lineno, colno, error) { ... }
  • message:错误信息(字符串)。可用于 HTML onerror=""处理程序中的event
  • source:发生错误的脚本 URL(字符串)
  • lineno:发生错误的行号(数字)
  • colno:发生错误的列号(数字)
  • errorError 对象(对象)

若该函数返回true,则阻止执行默认事件处理函数。

console.log("test", a)
window.onerror = function(message, source, lineno, colno, error) { 
    console.error("message", message)
    console.error("source", source)
    console.error("lineno", lineno)
    console.error("colno", colno)
    console.error("error", error)
    console.error("error.name", error.name)
    console.error("error.message", error.message)
}

image.png

2、addEventListener

window.addEventListener('error', function(event) { 
    console.log("addEventListener", event)
})

同一个错误,我们可以发现addEventListener拿到的信息更多 image.png

两者的区别是:

  • 两者都能监听到错误信息,window.onerror获取的是msg, url, lineNo, columnNo, error等一系列参数,而addEventListener获取的是events事件,包含了上面的信息和其他的一些信息,更全一些
  • addEventListener可以监听到资源错误信息,而window.onerror不能