路由守卫中抛出错误会中断导航并可能引发白屏,Vue Router 提供 router.onError 全局钩子统一捕获 beforeEach、beforeEnter 等守卫中的同步异常或 Promise 拒绝,支持错误上报、跳转错误页等处理,需在 createRouter 后、app.use(router) 前注册,且须确保异步守卫中 Promise 被正确 await 或 catch。
路由守卫中抛出错误会导致导航中断、白屏或控制台报错,但 Vue Router 提供了 onError 全局钩子来统一捕获和处理这类异常,避免应用崩溃。
在 beforeEach、beforeEnter 或组件内守卫(如 beforeRouteEnter)中,如果同步抛出错误(throw new Error(...)),或异步操作(如 API 调用)被拒绝(Promise.reject()),就会触发导航失败。此时 Vue Router 不会自动处理,错误会冒泡到全局,可能阻塞后续跳转。
router.onError 捕获所有跳转异常在创建路由实例后,调用 router.onError() 注册一个错误处理器,它会在任何守卫抛错时被调用,参数是错误对象:
createRouter 之后、app.use(router) 之前注册message、stack,也可能携带自定义属性(比如你 throw { code: 'AUTH_REQUIRED' })next() 或 router.push())示例:
const router = createRouter({ ... })router.onError((error) => { console.error('路由跳转异常:', error) if (error?.code === 'AUTH_REQUIRED') { router.push('/login') } else if (error?.name === 'NavigationFailure') { // 忽略已知的导航失败(如重复跳转) } else { router.push('/500') }})app.use(router)
与其在守卫里写一堆 if-else + router.push(),不如统一抛出自定义错误,再由 onError 统一响应:
beforeEach 中检查登录态,未登录就 throw { code: 'NOT_LOGGED_IN' }
throw new Error('Permission denied'),并在 onError 中映射到对应页面或提示onError 只捕获守卫执行期间抛出的错误,不捕获组件 setup 或 onBeforeRouteUpdate 中未被 await 的 Promise 拒绝。务必确保:
await 或 .catch() 处理,否则可能静默失败return next(false) 或 router.push(),否则导航会挂起onError 里 alert(error.message) 快速定位问题源头