]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat(errors): add to and from to router.onError()`
authorEduardo San Martin Morote <posva13@gmail.com>
Mon, 14 Jun 2021 13:46:34 +0000 (15:46 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Mon, 14 Jun 2021 13:46:34 +0000 (15:46 +0200)
__tests__/errors.spec.ts
src/router.ts

index 8dd323f76261a309f16c74f6a985b48dff49a4a3..3f652795f2237430d895a1d1f9710022de5380f9 100644 (file)
@@ -13,6 +13,7 @@ import {
   NavigationGuard,
   RouteLocationRaw,
   START_LOCATION_NORMALIZED,
+  RouteLocationNormalized,
 } from '../src/types'
 
 const routes: RouteRecordRaw[] = [
@@ -146,6 +147,25 @@ describe('Errors & Navigation failures', () => {
     }, error)
   })
 
+  it('triggers onError with to and from', async () => {
+    const { router } = createRouter()
+    let expectedTo: RouteLocationNormalized | undefined
+    let expectedFrom: RouteLocationNormalized | undefined
+    const error = new Error()
+    router.beforeEach((to, from) => {
+      expectedTo = to
+      expectedFrom = from
+      throw error
+    })
+
+    await expect(router.push('/foo')).rejects.toEqual(error)
+
+    expect(afterEach).toHaveBeenCalledTimes(0)
+    expect(onError).toHaveBeenCalledTimes(1)
+
+    expect(onError).toHaveBeenCalledWith(error, expectedTo, expectedFrom)
+  })
+
   it('triggers onError with rejected promises', async () => {
     let error = new Error()
     await testError(async () => {
@@ -337,7 +357,11 @@ async function testError(
   expect(afterEach).toHaveBeenCalledTimes(0)
   expect(onError).toHaveBeenCalledTimes(1)
 
-  expect(onError).toHaveBeenCalledWith(expectedError)
+  expect(onError).toHaveBeenCalledWith(
+    expectedError,
+    expect.any(Object),
+    expect.any(Object)
+  )
 }
 
 async function testNavigation(
@@ -425,5 +449,9 @@ async function testHistoryError(
   expect(afterEach).toHaveBeenCalledTimes(0)
   expect(onError).toHaveBeenCalledTimes(1)
 
-  expect(onError).toHaveBeenCalledWith(expectedError)
+  expect(onError).toHaveBeenCalledWith(
+    expectedError,
+    expect.any(Object),
+    expect.any(Object)
+  )
 }
index 9393ddccaed17532580c9c8837edbbd0dc38f51b..5cc118fd6696cd9b00ddf30574ed4383ae1aa9d1 100644 (file)
@@ -70,9 +70,17 @@ import { addDevtools } from './devtools'
 
 /**
  * Internal type to define an ErrorHandler
+ *
+ * @param error - error thrown
+ * @param to - location we were navigating to when the error happened
+ * @param from - location we were navigating from when the error happened
  * @internal
  */
-export type _ErrorHandler = (error: any) => any
+export type _ErrorHandler = (
+  error: any,
+  to: RouteLocationNormalized,
+  from: RouteLocationNormalizedLoaded
+) => any
 // resolve, reject arguments of Promise constructor
 type OnReadyCallback = [() => void, (reason?: any) => void]
 
@@ -664,7 +672,7 @@ export function createRouter(options: RouterOptions): Router {
         isNavigationFailure(error)
           ? error
           : // reject any unknown error
-            triggerError(error)
+            triggerError(error, toLocation, from)
       )
       .then((failure: NavigationFailure | NavigationRedirectError | void) => {
         if (failure) {
@@ -979,7 +987,7 @@ export function createRouter(options: RouterOptions): Router {
           // do not restore history on unknown direction
           if (info.delta) routerHistory.go(-info.delta, false)
           // unrecognized error, transfer to the global handler
-          return triggerError(error)
+          return triggerError(error, toLocation, from)
         })
         .then((failure: NavigationFailure | void) => {
           failure =
@@ -1012,14 +1020,21 @@ export function createRouter(options: RouterOptions): Router {
 
   /**
    * Trigger errorHandlers added via onError and throws the error as well
+   *
    * @param error - error to throw
+   * @param to - location we were navigating to when the error happened
+   * @param from - location we were navigating from when the error happened
    * @returns the error as a rejected promise
    */
-  function triggerError(error: any): Promise<unknown> {
+  function triggerError(
+    error: any,
+    to: RouteLocationNormalized,
+    from: RouteLocationNormalizedLoaded
+  ): Promise<unknown> {
     markAsReady(error)
     const list = errorHandlers.list()
     if (list.length) {
-      list.forEach(handler => handler(error))
+      list.forEach(handler => handler(error, to, from))
     } else {
       if (__DEV__) {
         warn('uncaught error during route navigation:')
@@ -1072,7 +1087,7 @@ export function createRouter(options: RouterOptions): Router {
     return nextTick()
       .then(() => scrollBehavior(to, from, scrollPosition))
       .then(position => position && scrollToPosition(position))
-      .catch(triggerError)
+      .catch(err => triggerError(err, to, from))
   }
 
   const go = (delta: number) => routerHistory.go(delta)