接下来这篇文章我们就来详细学习一下前端监控系统中的,异常监控。
想要进行异常监控之前,肯定先要了解有哪些异常才能进行监控。
一般来说,浏览器端的异常分为两种类型:
而这里面我们又有各自的差异
先来说说JavaScript的错误类型,ECMA-262 定义了 7 种错误类型,说明如下:
EvalError :eval() 函数的相关的错误RangeError :使用了超出了 JavaScript 的限制或范围的值。ReferenceError: 引用了未定义的变量或对象TypeError: 类型错误URIError: URI操作错误SyntaxError: 语法错误 (这个错误WebIDL中故意省略,保留给ES解析器使用)Error: 普通异常,通常与 throw 语句和 try/catch 语句一起使用,利用属性 name 可以声明或了解异常的类型,利用message 属性可以设置和读取异常的详细信息。如果想更详细了解可以看详细错误罗列这篇文章
<img> 、<script>、<video>、<audio>、<iframe> 等标签加载的资源。new Image()等代码来实现初始化。那既然我们已经知道了我们的网站在客户端运行时可能会出现这些异常。那我们要如何进行捕获错误信息呢?
我们常见的几种捕捉方法有
try-catch (ES提供基本的错误捕获语法)window.onerror = cb (DOM0)window.addEventListener('error', cb, true) (DOM2)window.addEventListener("unhandledrejection", cb)(DOM4)Promise.then().catch(cb)封装XMLHttpRequest&fetch| 覆写请求接口对象可能我们之前只用过try-catch这种方法,其他的之前都没见过,没关系下面我们来逐个讲解。
try-catch 我们经常能看见,通过给代码块进行 try-catch 进行包装后,当代码块发生出错时 catch 将能捕捉到错误的信息,页面也将可以继续执行。
优点:
缺点:
捕捉同步代码
// 同步异常的捕获
function foo () {
doSomething()
}
try {
foo()
} catch (e) {
console.log(e)
// 可以打印出完整的错误堆栈信息
}无法捕捉异步代码示例
// 异步异常的捕获
function asyncFunc() {
setTimeout(() => {
throw new Error("这是一个异步代码中的错误");
}, 1000);
}
try {
asyncFunc();
} catch (e) {
// 获取不到任何信息!
}优点:
缺点:
代码示例:
window.onerror = function(message, source, line, column, error) {
// 输出错误信息
console.log("错误信息:" + message);
console.log("错误来源:" + source);
console.log("错误行号:" + line);
console.log("错误列号:" + column);
// 如果有错误对象,输出错误堆栈
if (error) {
console.log("错误堆栈:" + error.stack);
}
};注意:
优点:
缺点:
//监听错误
window.addEventListener('error', function(event) {
// 输出错误信息
console.log("错误信息:" + event.message);
console.log("错误来源:" + event.filename);
console.log("错误行号:" + event.lineno);
console.log("错误列号:" + event.colno);
// 如果有错误对象,输出错误堆栈
if (event.error) {
console.log("错误堆栈:" + event.error.stack);
}
}, true);
//监听微任务Promise异常
window.addEventListener('unhandledrejection', function(event) {
// 输出错误信息
console.log("错误信息:" + event.message);
console.log("错误来源:" + event.filename);
console.log("错误行号:" + event.lineno);
console.log("错误列号:" + event.colno);
// 如果有错误对象,输出错误堆栈
if (event.error) {
console.log("错误堆栈:" + event.error.stack);
}
}, true);优点:
缺点:
function fetchUserData() {
return new Promise((resolve, reject) => {
// 模拟异步请求
setTimeout(() => {
const random = Math.random();
if (random < 0.5) {
resolve({ name: "Alice", age: 25 });
} else {
reject(new Error("请求失败"));
}
}, 1000);
});
}
fetchUserData()
.then((data) => {
console.log("用户信息:", data);
})
.catch((error) => {
console.log("请求失败:", error.message);
});
// 示例:同步代码中的错误
try {
throw new Error("这是一个同步代码中的错误");
} catch (e) {
console.log(e);
}优点:
缺点:
// 覆写XMLHttpRequest API
if(!window.XMLHttpRequest) return;
var xmlhttp = window.XMLHttpRequest;
var _oldSend = xmlhttp.prototype.send;
var _handleEvent = function (event) {
if (event && event.currentTarget && event.currentTarget.status !== 200) {
report(event)
}
}
xmlhttp.prototype.send = function () {
if (this['addEventListener']) {
this['addEventListener']('error', _handleEvent);
this['addEventListener']('load', _handleEvent);
this['addEventListener']('abort', _handleEvent);
this['addEventListener']('close', _handleEvent);
} else {
var _oldStateChange = this['onreadystatechange'];
this['onreadystatechange'] = function (event) {
if (this.readyState === 4) {
_handleEvent(event);
}
_oldStateChange && _oldStateChange.apply(this, arguments);
};
}
return _oldSend.apply(this, arguments);
}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。