Vue Router 的 router.onError() 是路由守卫异常的统一捕获机制,可处理同步错误、await 的 Promise 拒绝及异步组件加载失败,但不捕获未 await 的 Promise 拒绝或组件生命周期错误。

“路由钩子的错误边界”不是 Vue Router 官方术语,而是开发者对 守卫执行过程中异常未被捕获时导致导航中断、白屏或不可控跳转 这一现象的形象描述。它本质上指:路由守卫(如 beforeEach、beforeEnter)中抛出的同步错误或未处理的 Promise 拒绝,会直接穿透到 JavaScript 执行层,破坏导航流程——就像 React 中组件渲染出错会冒泡到最近的 ErrorBoundary 一样,这里缺少一个“兜底拦截点”,即所谓“边界”。Vue Router 通过 router.onError() 提供了这个边界。
源码层面如何区分处理同步与异步异常?
Vue Router 内部在导航解析阶段对守卫返回值/执行结果做了明确分类:
-
同步错误:守卫函数体中直接
throw new Error(...)或访问未定义属性等运行时错误,会被try...catch立即捕获,并作为导航失败原因传递给onError回调 -
异步拒绝(Promise rejection):当守卫是
async函数,或显式返回一个被拒绝的 Promise(如return fetch('/auth').then(r => r.json()).catch(() => { throw 'auth failed' })),Router 会await该 Promise,其reject值同样触发onError -
未 await 的 Promise 拒绝:若你在
async beforeEach中写了fetch('/api').catch(e => console.error(e))却没await或return它,这个拒绝不会进入 Router 的错误流,而是变成全局未处理 Promise 拒绝(触发window.addEventListener('unhandledrejection')),onError完全收不到
守卫内必须遵守的异常处理约定
要让 onError 真正起作用,守卫写法需满足两个前提:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 所有异步操作必须被
await(推荐)或return一个 Promise,不能放任其“游离”在守卫执行流之外 - 不依赖
next(false)或next('/login')隐式处理错误;应主动抛出自定义错误对象(如throw { code: 'NO_PERMISSION', to: '/403' }),由onError统一响应,保持守卫逻辑纯净
onError 是真正的“最后防线”
它能捕获三类源头异常:
- 全局前置/解析守卫中的同步抛错或 await 后的 Promise 拒绝
- 路由独享守卫(
beforeEnter)和组件内守卫(beforeRouteEnter)中同类异常 - 异步路由组件加载失败(例如
import('./Admin.vue')报 404 或语法错误)
但注意:onError 不处理组件 setup、onBeforeMount 等生命周期中抛出的错误,那些属于组件渲染错误,应由 errorCaptured 或全局 app.config.errorHandler 覆盖。


















