详解Vue 的异常处理机制


Posted in Vue.js onNovember 30, 2020

最近需要在业务中加一个全局的 filter,filter 会对输入进行验证,用于进行前端监控。其中一个要处理的问题,就是验证失败后如何发送异常日志,这个过程中顺便了解了一下 vue 的异常处理机制。

errorCaptured、errorHandler

vue 提供了两个 API 用于异常的捕获,分别是 errorCaptured 和 errorHandler:

  1. errorCaptured

errorCaptured 是组件的一个钩子函数,用于在组件级别捕获异常。当这个钩子函数返回 false 时,会阻止异常进一步向上冒泡,否则会不断向父组件传递,直到 root 组件。

  1. errorHandler

errorHandler 是一个全局的配置项,用来在全局捕获异常。例如Vue.config.errorHandler = function (err, vm, info) {}。

error.js

在 vue 源码中,异常处理的逻辑放在 /src/core/util/error.js 中:

import config from '../config'
import { warn } from './debug'
import { inBrowser } from './env'

export function handleError (err: Error, vm: any, info: string) {
 if (vm) {
  let cur = vm
  while ((cur = cur.$parent)) {
   const hooks = cur.$options.errorCaptured
   if (hooks) {
    for (let i = 0; i < hooks.length; i++) {
     try {
      const capture = hooks[i].call(cur, err, vm, info) === false
      if (capture) return
     } catch (e) {
      globalHandleError(e, cur, 'errorCaptured hook')
     }
    }
   }
  }
 }
 globalHandleError(err, vm, info)
}

function globalHandleError (err, vm, info) {
 if (config.errorHandler) {
  try {
   return config.errorHandler.call(null, err, vm, info)
  } catch (e) {
   logError(e, null, 'config.errorHandler')
  }
 }
 logError(err, vm, info)
}

function logError (err, vm, info) {
 if (process.env.NODE_ENV !== 'production') {
  warn(`Error in ${info}: "${err.toString()}"`, vm)
 }
 /* istanbul ignore else */
 if (inBrowser && typeof console !== 'undefined') {
  console.error(err)
 } else {
  throw err
 }
}

文件不长,向外暴露了一个 handleError 方法,在需要捕获异常的地方调用。handleError 方法中首先获取到报错的组件,之后递归查找当前组件的父组件,依次调用 errorCaptured 方法。在遍历调用完所有 errorCaptured 方法、或 errorCaptured 方法有报错时,会调用 globalHandleError 方法。

globalHandleError 方法调用了全局的 errorHandler 方法。

如果 errorHandler 方法自己又报错了呢?生产环境下会使用 console.error 在控制台中输出。

可以看到 errorCaptured 和 errorHandler 的触发时机都是相同的,不同的是 errorCaptured 发生在前,且如果某个组件的 errorCaptured 方法返回了 false,那么这个异常信息不会再向上冒泡也不会再调用 errorHandler 方法。

以上就是详解Vue 的异常处理机制的详细内容,更多关于vue 异常处理的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
vue中音频wavesurfer.js的使用方法
Feb 20 Vue.js
vue $router和$route的区别详解
Dec 02 Vue.js
vuex Module将 store 分割成模块的操作
Dec 07 Vue.js
vue中实现点击空白区域关闭弹窗的两种方法
Dec 30 Vue.js
Vue看了就会的8个小技巧
Jan 21 Vue.js
Vue仿Bibibili首页的问题
Jan 21 Vue.js
vue中h5端打开app(判断是安卓还是苹果)
Feb 26 Vue.js
深入理解Vue的数据响应式
May 15 Vue.js
一文带你理解vue创建一个后台管理系统流程(Vue+Element)
May 18 Vue.js
一篇文章告诉你如何实现Vue前端分页和后端分页
Feb 18 Vue.js
vue实现简易音乐播放器
Aug 14 Vue.js
ESLint 是如何检查 .vue 文件的
Nov 30 #Vue.js
Vue用mixin合并重复代码的实现
Nov 27 #Vue.js
使用vue编写h5公众号跳转小程序的实现代码
Nov 27 #Vue.js
在Vue中使用CSS3实现内容无缝滚动的示例代码
Nov 27 #Vue.js
vuex的数据渲染与修改浅析
Nov 26 #Vue.js
vue动态合并单元格并添加小计合计功能示例
Nov 26 #Vue.js
vue单元格多列合并的实现
Nov 26 #Vue.js
You might like
PHP反转字符串函数strrev()函数的用法
2012/02/04 PHP
php操作路径的经典方法(必看篇)
2016/10/04 PHP
引用外部js乱码问题分析及解决方案
2013/04/12 Javascript
jQuery获取浏览器中的分辨率实现代码
2013/04/23 Javascript
热点新闻滚动特效的js代码
2013/08/17 Javascript
js获得页面的高度和宽度的方法
2014/02/23 Javascript
微信小程序 教程之WXSS
2016/10/18 Javascript
解析AngularJS中get请求URL出现的跨域问题
2016/12/01 Javascript
JavaScript函数参数的传递方式详解
2017/03/06 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
2017/10/15 Javascript
js实现鼠标单击Tab表单切换效果
2018/05/16 Javascript
Smartour 让网页导览变得更简单(推荐)
2019/07/19 Javascript
[43:49]LGD vs CHAOS 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python3 入门教程 简单但比较不错
2009/11/29 Python
详解Python中的strftime()方法的使用
2015/05/22 Python
Python之str操作方法(详解)
2017/06/19 Python
python实现神经网络感知器算法
2017/12/20 Python
Python设计模式之代理模式简单示例
2018/01/09 Python
python2.7实现复制大量文件及文件夹资料
2019/08/31 Python
Python 实现自动完成A4标签排版打印功能
2020/04/09 Python
世界上最大的街头服饰网站:Karmaloop
2017/02/04 全球购物
联想加拿大官方网站:Lenovo Canada
2018/04/05 全球购物
阿根廷票务网站:StubHub阿根廷
2018/04/13 全球购物
英国剑桥包中文官网:The Cambridge Satchel Company中国
2018/11/06 全球购物
廉价连衣裙和婚纱礼服在线销售:Tbdress
2019/02/28 全球购物
护理专业毕业生推荐信
2013/10/31 职场文书
职业生涯规划书基本格式
2014/01/06 职场文书
风险评估实施方案
2014/03/09 职场文书
银行柜员求职自荐书
2014/06/18 职场文书
大学社团招新的通讯稿
2014/09/10 职场文书
2014社会治安综合治理工作总结
2014/12/04 职场文书
《1942》观后感
2015/06/08 职场文书
施工安全责任协议书
2016/03/23 职场文书
Vue实现动态查询规则生成组件
2021/05/27 Vue.js
Python人工智能之混合高斯模型运动目标检测详解分析
2021/11/07 Python
MySQL分区以及建索引的方法总结
2022/04/13 MySQL