跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScript大前端

构建 Vue 全局错误处理体系,实现业务与错误解耦

探讨了 Vue 项目中全局错误处理的必要性与设计方法。首先阐述了将业务逻辑与错误处理解耦以及为监控提供统一入口的重要性。接着介绍了 Vue 3 中 app.config.errorHandler 的基础用法及其捕获范围。进阶部分提出了定义可识别业务错误基类、在 errorHandler 中进行分类处理、补齐 Promise reject 捕获能力以及采用策略模式封装错误处理策略的方案。最终目标是提升项目的可维护性和长期稳定性。

人间失格发布于 2026/4/5更新于 2026/7/851 浏览
构建 Vue 全局错误处理体系,实现业务与错误解耦

构建 Vue 全局错误处理体系,实现业务与错误解耦

在之前的实践中,曾分享过替代传统 try-catch 的链式调用封装思路,以及网络层面的 Axios 错误处理封装方案。但这些方案多局限于特定场景,难以完全满足生产环境下的项目需求。因此,构建一套全局错误处理机制显得尤为重要。

全局错误处理示意图

一、为什么要做全局错误处理?

1、将业务逻辑与错误处理解耦

在业务模块中,我们真正关心的是数据是否可用,以及页面状态如何变化,并不关心网络异常的类型、提示和跳转。所以需要将错误策略抽离到全局层,让业务代码只专注于处理业务,全局错误处理层专注于处理各类错误,解耦后业务层和全局错误层都更加纯粹,也更有利于长期维护和拓展。

2、为监控和埋点提供统一入口

项目上线后,对于错误信息除了要建立临时应对和处理机制外,还需要定时收集和上报,给错误分级,还要收集用户的环境信息,这样才能给开发者提供准确的数据信息,从而针对性的修复 bug 以及性能优化。

二、Vue 中的基础全局错误处理方式

1、Vue 中全局错误处理写法

在 Vue 3 中,官方提供了一个明确的入口:app.config.errorHandler。在 main.js 中,添加如下代码即可:

const app = createApp(App)
app.config.errorHandler = (err, instance, info) => {
  console.error(err)
}

2、它会捕获哪些错误?

app.config.errorHandler 只会捕获 Vue 运行时上下文中的错误,包括:

  • 组件 setup / render 中的同步错误
  • 生命周期钩子中的错误
  • 模板渲染期间的错误
  • watch / computed 中抛出的错误
  • 被 Vue 追踪的 Promise 链中的错误

3、它不会捕获哪些错误?

不在上述范围内,脱离了 Vue 的响应式调度体系的错误均不会被捕获,比如:

setTimeout(() => {
  throw new Error('timeout error') // 不会捕获
})
fetch('/api').then(() => {
  throw  () 
})
new
Error
'fetch error'
// 不会捕获

所以 Promise 的 reject 并不会天然进全局错误处理,后面进阶方案里会解决这个问题。

4、errorHandler 的参数含义

Vue 3 中的定义如下:

app.config.errorHandler = ( err: unknown, instance: ComponentPublicInstance | null, info: string ) => void

三个参数的具体意义为:

app.config.errorHandler = (err, instance, info) => {
  console.log(err) // 实际抛出的错误对象
  console.log(instance) // 出错的组件实例(可能为 null)
  console.log(info) // 错误来源描述(字符串)
}

三、全局错误处理的进阶设计

1、定义'可识别的业务错误'

真正的工程实践中,我们关心错误是为了解决错误,所以需要对业务错误进行鉴别分类。

首先需要定义可识别的业务错误基类及其派生类,比如:

export class BusinessError extends Error {
  constructor(message, code) {
    super(message)
    this.code = code
    this.isBusinessError = true
  }
}

export class AuthError extends BusinessError {
  constructor(message = '登录已失效') {
    super(message, 'AUTH_ERROR')
  }
}

export class PermissionError extends BusinessError {
  constructor(message = '没有操作权限') {
    super(message, 'PERMISSION_ERROR')
  }
}

在具体的业务代码中,遇到错误时,就使用对应的错误类实例化并抛出,app.config.errorHandler 就会捕获到这个错误实例,比如:

if (!token) {
  throw new AuthError()
}

2、在 errorHandler 中做真正的'分类处理'

现在,在定义了可识别的业务错误之后,全局错误处理的优势就体现出来了,此时业务错误类型可控,有基础应对手段,并且还有错误上报策略 reportError 以应对突发情况:

app.config.errorHandler = (err, instance, info) => {
  if (err instanceof BusinessError) {
    handleBusinessError(err)
    return
  }
  handleUnknownError(err, instance, info)
}
export function handleBusinessError(err) {
  ElMessage.warning(err.message)
  if (err.code === 'AUTH_ERROR') {
    router.push('/login')
  }
}

export function handleUnknownError(err, instance, info) {
  ElMessage.error('系统异常,请稍后再试')
  reportError({ err, component: instance?.type?.name, info, })
}

export function reportError({ err, component, info }) {
  const payload = {
    message: err.message,
    stack: err.stack,
    component,
    info,
    ua: navigator.userAgent,
    time: Date.now(),
  }
  fetch('/error/report', {
    method: 'POST',
    body: JSON.stringify(payload),
  })
}

reportError 方法收集了错误的类型、信息、位置、发生时间,客户端的类型、操作系统、浏览器版本等信息,集中上报等待解决。

3、补齐 Promise reject 的捕获能力

前面说过,errorHandler 不会自动捕获所有 Promise 的 reject,工程中常见解决方案是在请求层统一转抛错误,这就回到了文章开头时我们提到的在网络层面实现数据与状态解耦的 Axios 错误处理封装方案,由于那篇博文已经详细介绍过了,这里只给个简要的例子:

axios.interceptors.response.use(
  res => res,
  err => {
    throw err // 重新抛给 Vue
  }
)

这样就能保证所有异常最终都会汇聚到一个出口。

4、错误处理的策略化封装

看到这个词有些粉丝可能会有印象,以前的博文也提到过策略表模式,在全局错误处理中依然好用,这样就不用在 errorHandler 里写一堆 if else 了,更容易拓展和维护,比如:

app.config.errorHandler = (err) => {
  const handler = errorStrategyMap[err.code] || errorStrategyMap.default
  handler(err)
}
const errorStrategyMap = {
  AUTH_EXPIRED: (err) => {
    ElMessage.error(err.message)
    router.push('/login')
  },
  default: (err) => {
    ElMessage.error('系统异常')
    reportError(err)
  }
}

四、结语

通过进阶的全局错误处理设计,将业务逻辑与错误处理解耦,不仅能让页面代码更加清晰简洁,还能实现错误的分级处理,从而显著提升项目在生产环境中的可维护性和长期稳定性。

只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。

目录

  1. 构建 Vue 全局错误处理体系,实现业务与错误解耦
  2. 一、为什么要做全局错误处理?
  3. 1、将业务逻辑与错误处理解耦
  4. 2、为监控和埋点提供统一入口
  5. 二、Vue 中的基础全局错误处理方式
  6. 1、Vue 中全局错误处理写法
  7. 2、它会捕获哪些错误?
  8. 3、它不会捕获哪些错误?
  9. 4、errorHandler 的参数含义
  10. 三、全局错误处理的进阶设计
  11. 1、定义“可识别的业务错误”
  12. 2、在 errorHandler 中做真正的“分类处理”
  13. 3、补齐 Promise reject 的捕获能力
  14. 4、错误处理的策略化封装
  15. 四、结语
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 鸿蒙金融理财全栈项目安全合规与用户体验优化
  • 法律领域自然语言处理(NLP)应用与实战
  • C++ STL 常用算法详解:序列、排序与数值处理
  • Java IO 流进阶:字符流与字节流的核心应用
  • GitHub 机器人故障处理:从 403 错误到权限重构
  • C++ 跨平台开发的挑战与应对策略
  • Git 入门指南:代码版本管理实战
  • C 语言 Web 开发实战:CGI、FastCGI 与 Nginx 模块详解
  • IntelliJ IDEA 类与方法注释模板配置
  • Spring Boot 药品进销存信息管理系统设计与实现
  • PyTorch 2.0 深度学习入门与实战指南
  • Python 副业开发指南:技术栈与实战方向解析
  • LIBERO 开源机器人学习框架:架构解析与实战
  • CSS 文字与段落排版详解
  • JDK9 及以上版本适配 wsimport 生成的 SOAP 代码
  • RAG 检索增强生成技术实战与架构解析
  • 二叉搜索树深度解析:原理、实现与算法应用
  • 医疗 AI 场景下逻辑回归算法深度解析
  • Flutter × HarmonyOS 6 实战落地:跨平台工具应用开发复盘
  • C++ AVL 树原理与实现详解

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online