|
3 | 3 | * SPDX-License-Identifier: AGPL-3.0-or-later |
4 | 4 | */ |
5 | 5 | import type { RawLocation, Route } from 'vue-router' |
6 | | -import type { ErrorHandler } from 'vue-router/types/router.d.ts' |
7 | 6 |
|
8 | 7 | import { loadState } from '@nextcloud/initial-state' |
9 | 8 | import { generateUrl } from '@nextcloud/router' |
10 | 9 | import queryString from 'query-string' |
11 | | -import Router from 'vue-router' |
| 10 | +import Router, { isNavigationFailure, NavigationFailureType } from 'vue-router' |
12 | 11 | import Vue from 'vue' |
| 12 | +import logger from '../services/logger' |
13 | 13 |
|
14 | 14 | const view = loadState<string>('files_sharing', 'view') |
15 | 15 | const sharingToken = loadState<string>('files_sharing', 'sharingToken') |
16 | 16 |
|
17 | 17 | Vue.use(Router) |
18 | 18 |
|
19 | 19 | // Prevent router from throwing errors when we're already on the page we're trying to go to |
20 | | -const originalPush = Router.prototype.push as (to, onComplete?, onAbort?) => Promise<Route> |
21 | | -Router.prototype.push = function push(to: RawLocation, onComplete?: ((route: Route) => void) | undefined, onAbort?: ErrorHandler | undefined): Promise<Route> { |
22 | | - if (onComplete || onAbort) return originalPush.call(this, to, onComplete, onAbort) |
23 | | - return originalPush.call(this, to).catch(err => err) |
| 20 | +const originalPush = Router.prototype.push |
| 21 | +Router.prototype.push = (function(this: Router, ...args: Parameters<typeof originalPush>) { |
| 22 | + if (args.length > 1) { |
| 23 | + return originalPush.call(this, ...args) |
| 24 | + } |
| 25 | + return originalPush.call<Router, [RawLocation], Promise<Route>>(this, args[0]).catch(ignoreDuplicateNavigation) |
| 26 | +}) as typeof originalPush |
| 27 | + |
| 28 | +const originalReplace = Router.prototype.replace |
| 29 | +Router.prototype.replace = (function(this: Router, ...args: Parameters<typeof originalReplace>) { |
| 30 | + if (args.length > 1) { |
| 31 | + return originalReplace.call(this, ...args) |
| 32 | + } |
| 33 | + return originalReplace.call<Router, [RawLocation], Promise<Route>>(this, args[0]).catch(ignoreDuplicateNavigation) |
| 34 | +}) as typeof originalReplace |
| 35 | + |
| 36 | +/** |
| 37 | + * Ignore duplicated-navigation error but forward real exceptions |
| 38 | + * @param error The thrown error |
| 39 | + */ |
| 40 | +function ignoreDuplicateNavigation(error: unknown): void { |
| 41 | + if (isNavigationFailure(error, NavigationFailureType.duplicated)) { |
| 42 | + logger.debug('Ignoring duplicated navigation from vue-router', { error }) |
| 43 | + } else { |
| 44 | + throw error |
| 45 | + } |
24 | 46 | } |
25 | 47 |
|
26 | 48 | const router = new Router({ |
|
0 commit comments