内容简介:快速定位线上问题,捕获一些由于特殊情况导致的无法重现的客户问题但是然而对于语法错误和异步错误就捕捉不到了 示例:语法错误
基础认知:
快速定位线上问题,捕获一些由于特殊情况导致的无法重现的客户问题
JS 处理异常的方式
try-catch 异常处理
但是 try-catch 处理异常的能力有限, 只能捕获捉到运行时非异步错误,对于语法错误和异步错误就显得无能为力,捕捉不到 。
下面是try-catch基本使用场景
示例:运行时错误
try {
error // 未定义变量
} catch(e) {
console.log('我知道错误了');
console.log(e);
}
然而对于语法错误和异步错误就捕捉不到了 示例:语法错误
try {
// ;符号大写,其实这种错误一般不会出现,因为在前期编辑器阶段就会体现出现,不会让程序正常发布
var error = 'error';
} catch(e) {
console.log('我感知不到错误');
console.log(e);
}
它会在开发的时候,浏览器就会报这个错误
window.onerror 异常处理
window.onerror 捕获异常能力比 try-catch 稍微强点,无论是异步还是非异步错误,onerror 都能捕获到运行时错误。
示例:运行时同步错误
/**
* @param {String} msg 错误信息
* @param {String} url 出错文件
* @param {Number} row 行号
* @param {Number} col 列号
* @param {Object} error 错误详细信息
*/
window.onerror=function(msg, url, row, col, error){
console.log('我知道错误了');
console.log({
msg, url, row, col, error
})
return true;
};
error;
示例:异步错误
window.onerror=function(msg,url,row,col,error){
console.log('我知道异步错误了');
console.log({
msg, url, row, col, error
})
return true;
};
//定时器异步
setTimeout(() => {
error;
});
关于 window.onerror 还有两点需要值得注意
-
1.对于
onerror这种全局捕获,最好写在所有JS脚本的前面,因为你无法保证你写的代码是否出错,如果写在后面,一旦发生错误的话是不会被onerror捕获到的。 -
2.另外
onerror是无法捕获到网络异常的错误。
当我们遇到 <img src="./404.png"> 报 404 网络请求异常的时候, onerror 是无法帮助我们捕获到异常的。
可以看到没具体的错误信息和错误状态,但是有一个错误目标对象
这点知识还是需要知道,要不然用户访问网站,图片 CDN 无法服务,图片加载不出来而开发人员没有察觉就尴尬了。
Promise 错误
通过 Promise 可以帮助我们解决异步回调地狱的问题,但是一旦 Promise 实例抛出异常而你没有用 catch 去捕获的话, onerror 或 try-catch 也无能为力,无法捕捉到错误。
window.addEventListener('error',(msg,url,row,col,error)=>{
console.log('我感知不到 promise 错误');
console.log(
msg, url, row, col, error
);
}, true);
Promise.reject('promise error');
new Promise((resolve, reject) => {
reject('promise error');
});
new Promise((resolve) => {
resolve();
}).then(() => {
throw 'promise error'
});
所以我们需要主动监听 Promise 抛出的全局异常
window.addEventListener("unhandledrejection",function(e){
e.preventDefault()
console.log('我知道 promise 的错误了');
console.log(e.reason);
return true;
});
Promise.reject('promise error');
new Promise((resolve, reject) => {
reject('promise error');
});
new Promise((resolve) => {
resolve();
}).then(() => {
throw 'promise error'
});
前端异常监控现状
Vue全局异常捕获
Vue 全局配置 errorHandler 可以进行全局错误收集,我们可以根据这个特性对前端异常做这样的处理:业务错误直接写在业务里;代码错误、 ajax 请求异常等错误可以进行全局捕获然后抛出,不至于前端页面挂掉
-
代码层面的错误
import Vue from 'vue'
/**
* err object 异常信息
* vm 错误异常实例
* info 是 Vue 特定的错误信息
*/
// 只在 2.2.0+ 可用
Vue.config.errorHandler=function(err,vm,info){
//此处处理具体的错误信息
return true;
}
但是由于 errorHandler 无法捕获 promise 抛出的异常和网络层面资源的异常,所以还需要添加
//捕捉Promise异常
window.addEventListener("unhandledrejection",function(e){
});
//捕获网络错误,资源错误这些类似的错误,需要添加以下事件监听
window.addEventListener("error", function(e){
});
// 记住
window.addEventListener("error",()=>{})
和
`window.onerror=()=>{}`是由区别的
一个让你很开心的Api
navigator.sendBeacon() 方法可用于通过HTTP将少量数据异步传输到Web服务器。
-
数据可靠,浏览器关闭请求也照样能发
-
异步执行,不会影响下一页面的加载
-
同时不会延迟页面的卸载或影响下一导航的载入性能
-
API使用简单
window.addEventListener('unload',logData,false);
function logData(){
navigator.sendBeacon("http://mob/api/sendLog",{
//参数
});
}
浏览器兼容性很乐观
实现方案
1:数据传递部分 根据浏览器兼容是否支持 navigator.sendBeacon ,如果支持使用 navigator.sendBeacon 发送数据,如果不支持使用创建 Image 标签的形式发送数据
var img = new Image();
img.onload =function (){
}
img.src = `http://code/api/sendLog?data=${JSON.stringify({})}`;
//或者
window.addEventListener('unload', function(){
navigator.sendBeacon("http://code/api/sendLog",{});
}, false);
2:需要收集的数据部分
{
accountId:"账号标识ID",
url:"当前页面URL",
browser:"所属浏览器",
version:"浏览器版本",
system:"所属系统",
referer:"入口页面",
jsPath:"异常js文件路径",
errorObj:"异常错误信息json字符串",
connection:"连接网络情况"
}
下一篇将分享具体的功能实现,关注我下篇文件见
最 后
如 果 你 觉 得 这 篇 内 容 对 你 挺 有 启 发 :
我 这 么 帅 , 你 不 点 个 再 看 介 绍 给 妹 子 ?
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。