从0 到 1 开始前端异常监控

基础认知:
快速定位线上问题,捕获一些由于特殊情况导致的无法重现的客户问题

JS 处理异常的方式
try-catch 异常处理
但是 try-catch处理异常的能力有限, 只能捕获捉到运行时非异步错误,对于语法错误和异步错误就显得无能为力,捕捉不到 。

下面是try-catch基本使用场景

示例:运行时错误

try {
  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去捕获的话,onerrortry-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;
 }
 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:"连接网络情况"
}

有想了解更多的小伙伴可以加Q群链接里面看一下,应该对你们能够有所帮助。

有想了解更多前端的技术可以加Q群:1093606290

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值