import fakePromise from 'faked-promise'
import { createRouter as newRouter, createMemoryHistory } from '../src'
-import { NavigationFailure, NavigationFailureType } from '../src/errors'
+import {
+ NavigationFailure,
+ NavigationFailureType,
+ isNavigationFailure,
+ createRouterError,
+ ErrorTypes,
+} from '../src/errors'
import { components, tick } from './utils'
-import { RouteRecordRaw, NavigationGuard, RouteLocationRaw } from '../src/types'
+import {
+ RouteRecordRaw,
+ NavigationGuard,
+ RouteLocationRaw,
+ START_LOCATION_NORMALIZED,
+} from '../src/types'
const routes: RouteRecordRaw[] = [
{ path: '/', component: components.Home },
})
})
+describe('isNavigationFailure', () => {
+ const from = START_LOCATION_NORMALIZED
+ const to = from
+ it('non objects', () => {
+ expect(isNavigationFailure(null)).toBe(false)
+ expect(isNavigationFailure(true)).toBe(false)
+ expect(isNavigationFailure(false)).toBe(false)
+ })
+
+ it('errors', () => {
+ expect(isNavigationFailure(new Error())).toBe(false)
+ })
+
+ it('any navigation failure', () => {
+ expect(
+ isNavigationFailure(
+ createRouterError<NavigationFailure>(ErrorTypes.NAVIGATION_ABORTED, {
+ from,
+ to,
+ })
+ )
+ ).toBe(true)
+ })
+
+ it('specific navigation failure', () => {
+ expect(
+ isNavigationFailure(
+ createRouterError<NavigationFailure>(ErrorTypes.NAVIGATION_ABORTED, {
+ from,
+ to,
+ }),
+ NavigationFailureType.aborted
+ )
+ ).toBe(true)
+ })
+
+ it('multiple navigation failure types', () => {
+ expect(
+ isNavigationFailure(
+ createRouterError<NavigationFailure>(ErrorTypes.NAVIGATION_ABORTED, {
+ from,
+ to,
+ }),
+ NavigationFailureType.aborted | NavigationFailureType.cancelled
+ )
+ ).toBe(true)
+ expect(
+ isNavigationFailure(
+ createRouterError<NavigationFailure>(ErrorTypes.NAVIGATION_CANCELLED, {
+ from,
+ to,
+ }),
+ NavigationFailureType.aborted | NavigationFailureType.cancelled
+ )
+ ).toBe(true)
+ expect(
+ isNavigationFailure(
+ createRouterError<NavigationFailure>(ErrorTypes.NAVIGATION_DUPLICATED, {
+ from,
+ to,
+ }),
+ NavigationFailureType.aborted | NavigationFailureType.cancelled
+ )
+ ).toBe(false)
+ })
+})
+
async function testError(
nextArgument: any | NavigationGuard,
expectedError: Error | void = undefined,
}
}
+/**
+ * Check if an object is a {@link NavigationFailure}.
+ *
+ * @example
+ * ```js
+ * import { isNavigationFailure, NavigationFailureType } from 'vue-router'
+ *
+ * router.afterEach((to, from, failure) => {
+ * // Any kind of navigation failure
+ * if (isNavigationFailure(failure)) {
+ * // ...
+ * }
+ * // Only duplicated navigations
+ * if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
+ * // ...
+ * }
+ * // Aborted or canceled navigations
+ * if (isNavigationFailure(failure, NavigationFailureType.aborted | NavigationFailureType.canceled)) {
+ * // ...
+ * }
+ * })
+ * ```
+ * @param error - possible {@link NavigationFailure}
+ * @param type - optional types to check for
+ */
export function isNavigationFailure(
error: any,
- type: ErrorTypes.NAVIGATION_GUARD_REDIRECT
+ type?: ErrorTypes.NAVIGATION_GUARD_REDIRECT
): error is NavigationRedirectError
export function isNavigationFailure(
error: any,
- type: ErrorTypes
+ type?: ErrorTypes | NavigationFailureType
): error is NavigationFailure
export function isNavigationFailure(
error: any,
type?: number
): error is NavigationFailure {
return (
+ error instanceof Error &&
NavigationFailureSymbol in error &&
(type == null || !!((error as NavigationFailure).type & type))
)