目录背景onerrorelement.onerrorerrorHandlererrorCapturederror传播规则(划重点)如何监听异步错误总结背景 在开发Vue项目时,使用浏
在开发Vue项目时,使用浏览器调试可以比较清晰的看到报的什么错、在哪报错,或者使用console.log()打印出报错信息,以便快速定位到报错源头并解决,但是如果项目上线了又怎么查看呢。对于上线项目来说,一般都是会有代码混淆以及禁用console.log(),这个时候再使用浏览器调试就有点不太方便了。另一种场景,如果要做一个前端报错监控平台,那这些报错信息又应该如何收集呢。本文就重点介绍四种方式,即error、unhandledrejection、errorHandler、errorCaptured,用于监听Vue项目可能遇到的报错。
当javascript运行时错误,包括语法错误,则window会触发ErrorEvent接口的error事件,并执行window.onerror()方法,用于处理监听到的错误。
如果是资源加载失败,包括img的src加载失败或者引入的script加载失败,则加载资源的元素会触发Event接口的error事件,并指定该元素上的onerror()方法处理错误。这些error不会冒泡到window,也就是说window.onerror将无法监听到报错。
特点:
window.onerror
window.onerror接收4个参数,分别是:
完整用法:
window.onerror = function(message,source,line,column,error) {
// do something
};
如果函数返回true,则会阻止执行默认事件处理函数。
window.addEventListener('error')
使用事件监听,并在全局监听error事件。使用效果同window.onerror类似,语法有所差异:
window.addEventListener('error', event => {});
注意:此event指的是ErrorEvent类型,包含了有关事件以及具体的错误信息
举个栗子:(本文涉及的示例代码都是基于Vue项目,下同)
// App.vue
// window.onerror是全局监听,因此放在入口是比较合理的,尽管也可以放在其他位置
...
<script>
export default {
mounted() {
window.onerror = function(message,source,line,column,error) {
console.log('window.onerror----', message,source,line,column,error);
}
// 效果与上一个类似,都是挂载到全局,两者使用其一即可。如果两者都使用,会重复处理error
window.addEventListener('error', event => {
console.log('window error on listener---', event);
})
}
}
</script>
...
针对一些资源加载失败的情况,例如img、script,将会触发该元素的onerror()处理函数,并且error不会冒泡到window。遇到这种情况,可以手动抛出异常,就可以被全局异常监听到是资源加载失败了。
举个栗子
// child.vue
// 图片资源加载失败
<img src="123" alt="" @error="event => handleError(event)" />
...
handleError(event) {
console.log('handleError-----', event);
throw new Error('图片加载失败了'); // 手动抛出异常,以便全局事件可以监听到
}
Vue全局错误监听处理,所有组件的错误信息默认都会汇总到此。
由于errorHandler是全局配置的,因此window.onerror将会“失效”,即errorHandler能捕获的错误,onerror将不能捕获;errorHandler不能捕获的异常,onerror将捕获错误。如果errorCaptured函数返回为false,那么此error将不会传到errorHandler
举个栗子
// main.js
...
const app = createApp(App)
app.config.errorHandler = (err, vm info) => {
console.log('errorHandle', err, vm, info);
// err,错误对象
// vm,发生错误的组件实例
// info,Vue特定的错误信息,例如错误发生的生命周期、错误发生的事件
}
errorCaptured是Vue生命周期中的一个,用于捕获当前组件的所有后代组件产生的错误。函数如果返回为false,则会阻止error继续上传,全局的错误监听将不能捕获该error;否则,全局的错误监听也会再处理error。
此钩子接收三个参数:
在钩子函数中,可以修改组件的状态
tips:如果errorCaptured本身抛出error,return false也就不会执行了。
举个栗子也许更能说明白
代码写的比较简洁,但是“言简意赅”
// main.js
const app = createApp(App)
app.config.errorHandler = (err, vm info) => {
console.log('errorHandle', err, vm, info); // errorHandler也会执行两次
// err,错误对象
// vm,发生错误的组件实例
// info,Vue特定的错误信息,例如错误发生的生命周期、错误发生的事件
}
// App.vue
...
<!-- 引入父组件,并注册组件 -->
<FatherErrorDemo />
...
errorCaptured: (err, vm, info) => {
console.log('根组件 捕获异常 errorCaptured', err,vm,info)
// 根组件的errorCaptured会执行两次,先捕获FatherErrorDemo钩子自身的错误,然后捕获childErrorDemo的错误
// 因此vm也分别指向FatherErrorDemo和childErrorDemo
console.log('根组件 vm', vm.$data);
// return false;
}
// FatherErrorDemo.vue
...
<div>
this is FatherErrorDemo
<!-- 引入子组件,并注册组件 -->
<childErrorDemo />
</div>
...
errorCaptured: (err, vm, info) => {
console.log('父组件 错误捕获', err,vm,info);
console.log('父组件 vm', vm.$data); // vm 指向childErrorDemo实例
this.father(); // 未定义,此处会抛出错误。errorCaptured钩子函数自身产生错误
// return false;
}
// childErrorDemo.vue
...
<div>
this is childErrorDemo
</div>
...
mounted() {
this.child(); // 未定义,会抛出错误
}
执行结果:
根据执行过程可知:
异步错误无法直接使用Vue的errorCaptured和errorHandler来监听,根据异步类型的不同,处理方式有所差异。一般来说,监听异步错误,多采用window.onerror,如果是监听Promise的错误,则使用unhandledrejection事件来监听。
举个栗子吧
// main.js
const app = createApp(App)
app.config.errorHandler = (err, vm info) => {
console.log('errorHandle', err, vm, info); // errorHandler不会被调用
// err,错误对象
// vm,发生错误的组件实例
// info,Vue特定的错误信息,例如错误发生的生命周期、错误发生的事件
}
// App.vue
...
<!-- 引入父组件,并注册组件 -->
<FatherErrorDemo />
...
mounted() {
window.onerror = function(msg,source,line,column,err) {
console.log('window.onerror----', msg,source,line,column,err);
return true;
}
window.addEventListener('unhandledrejection', event => {
console.log('监听Promise unhandledrejection', event)
})
},
errorCaptured: (err, vm, info) => {
// errorCaptured不会被调用
console.log('根组件 捕获异常 errorCaptured', err,vm,info)
console.log('根组件 vm', vm.$data);
// return false;
}
// FatherErrorDemo.vue
...
<div>
this is FatherErrorDemo
</div>
...
mounted() {
setTimeout(() => {
this.father();
}, 1000); // 异步执行
new Promise((resolve, reject) => {
this.father();
resolve();
})
}
执行结果
由此可见,Vue的钩子和配置函数并没有执行,但是window.onerror、unhandledrejection却可以捕获到错误。
为了不写重复代码,setTimeout和Promise我放在一起了。实际上,Promise的产生错误且没有被reject处理,那么可以通过监听unhandledrejection事件来捕获异常。setTimeout产生的错误也只能用window.onerror来捕获(使用window.addEventListener('error')也是一样)。
到此这篇关于如何监听Vue项目报错的4种方式 的文章就介绍到这了,更多相关监听Vue项目报错内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: 如何监听Vue项目报错的4种方式
本文链接: https://www.lsjlt.com/news/146801.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0