一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

路由守卫抛出错误怎么办教你利用 onError 捕获全局跳转异常

时间:2026-07-23 11:02:48 编辑:袖梨 来源:一聚教程网

路由守卫中抛出错误会中断导航并可能引发白屏,Vue Router 提供 router.onError 全局钩子统一捕获 beforeEach、beforeEnter 等守卫中的同步异常或 Promise 拒绝,支持错误上报、跳转错误页等处理,需在 createRouter 后、app.use(router) 前注册,且须确保异步守卫中 Promise 被正确 await 或 catch。

路由守卫中抛出错误会导致导航中断、白屏或控制台报错,但 Vue Router 提供了 onError 全局钩子来统一捕获和处理这类异常,避免应用崩溃。

什么是路由守卫中的错误?

beforeEachbeforeEnter 或组件内守卫(如 beforeRouteEnter)中,如果同步抛出错误(throw new Error(...)),或异步操作(如 API 调用)被拒绝(Promise.reject()),就会触发导航失败。此时 Vue Router 不会自动处理,错误会冒泡到全局,可能阻塞后续跳转。

router.onError 捕获所有跳转异常

在创建路由实例后,调用 router.onError() 注册一个错误处理器,它会在任何守卫抛错时被调用,参数是错误对象:

  • 确保在 createRouter 之后、app.use(router) 之前注册
  • 错误对象通常包含 messagestack,也可能携带自定义属性(比如你 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 只捕获守卫执行期间抛出的错误,不捕获组件 setuponBeforeRouteUpdate 中未被 await 的 Promise 拒绝。务必确保:

  • 异步守卫中所有 Promise 都被 await.catch() 处理,否则可能静默失败
  • 不要在守卫里漏掉 return next(false)router.push(),否则导航会挂起
  • 调试时可临时在 onErroralert(error.message) 快速定位问题源头

热门栏目