Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Redirected from X to Y via a navigation guard. #3221

Closed
jasonlfunk opened this issue Jun 6, 2020 · 12 comments
Closed

Error: Redirected from X to Y via a navigation guard. #3221

jasonlfunk opened this issue Jun 6, 2020 · 12 comments

Comments

@jasonlfunk
Copy link

Version: 3.3.2

abort(createNavigationRedirectedError(current, route))

I have a Navigation Guard that does some various checks and redirects when necessary. Vue-router is not throwing this error when I do. Though everything is still working fine.

Is there a reason why this error is being thrown? What is the "correct" way to redirect via a navigation guard?

@vue-bot
Copy link

vue-bot commented Jun 6, 2020

Hello, thank you for taking time filling this issue!

However, we kindly ask you to use our Issue Helper when creating new issues, in order to ensure every issue provides the necessary information for us to investigate. This explains why your issue has been automatically closed by me (your robot friend!).

I hope to see your helper-created issue very soon!

@vue-bot vue-bot closed this as completed Jun 6, 2020
@posva
Copy link
Member

posva commented Jun 6, 2020

You probably redirecting correctly (next('/new-location')) although I can't tell without code. The errors have been exposed for a while now (see https://github.com/vuejs/vue-router/releases/tag/v3.1.0) and now we are making them real errors with properties so people can control what to do with navigation failures : vuejs/rfcs#150 (v4)

@jasonlfunk
Copy link
Author

jasonlfunk commented Jun 6, 2020 via email

@posva
Copy link
Member

posva commented Jun 6, 2020

Thanks for replying. The issue getting closed right away with the link to the issue creator really annoyed me. :)

I understand but do take the time next time to read what we write down please. We have put that there for a reason

@jasonlfunk
Copy link
Author

jasonlfunk commented Jun 6, 2020 via email

@soletan
Copy link

soletan commented Sep 10, 2020

Sorry, why do you need a fiddle to see that your code is logging an error for doing something that's part of intended behaviour and backed by your own documentation?

In your code there is an intended exception issued every time a guard is using next handler for replacing intended navigation target with a different one. But even then the redirection is performed. Maybe this exception is required to properly abort any ongoing transition in favour of a new one started. But this looks like an internal design/API issue of vue-router.

Next, there is your manual listing this scenario as a use case. I can't see any note there on having to live with an error logged to console on an unhandled promise rejection each time I use a guard for what it is intended for in many scenario by assuring prerequisites met prior to entering a route.

So, if this is intended behaviour, would you please elaborate on why dropping one routing target in favour of another one via guard is worth an error? And please add some information to the manual for that use case is anything but comprehensible by reading those docs.

@soletan
Copy link

soletan commented Sep 11, 2020

In addition: this error is currently breaking SSR side of VuePress build script. I expect currently given example for integrating vue-router with SSR is broken as well just because of this error on behalf of vue-router.

@soletan
Copy link

soletan commented Sep 11, 2020

Ok, AFAICT the 3.2.0 release of vue-router has introduced some breaking change of API thus failing to comply with semantic versioning.

@soletan
Copy link

soletan commented Sep 11, 2020

I've created a test project in https://github.com/soletan/vue-router-test.

  1. git checkout 0c5d
  2. yarn install --frozen-lockfile
  3. npm run build

This will fail. Next

  1. git checkout HEAD
  2. yarn install -frozen-lockfile
  3. npm run build

This time it will succeed. The change is about forcing VuePress to use vue-router 3.1.6 instead of 3.4.3.

Basically, I'm aware that there might be an issue with VueJS SSR doing something undocumented which is eventually causing this issue. But right now all I can see is that some software using vue-router was working fine at least until version 3.1.6 and stopped working in latest version. I haven't tested all the versions in between for sure. The release following 3.1.6 was 3.2.0, a minor release, thus expected to stay backward compatible. And this release was introducing changed behaviour in handling errors on redirecting routing transitions.

@soletan
Copy link

soletan commented Sep 19, 2020

You probably redirecting correctly (next('/new-location')) although I can't tell without code. The errors have been exposed for a while now (see https://github.com/vuejs/vue-router/releases/tag/v3.1.0) and now we are making them real errors with properties so people can control what to do with navigation failures : vuejs/rfcs#150 (v4)

I'd like to control to ignore those errors. This kind of control is out of scope for you, isn't it?

@soletan
Copy link

soletan commented Sep 19, 2020

(@posva haven't heard any updates on provided demonstration for the so called false alarm, would you mind sharing your 50 cents with me on this issue.)

Here is my sort final note on this issue:

  • https://jsfiddle.net/rypowk94/ is reproducing the mentioned behaviour when clicking on button visible after going to Foo. This fiddle is actually relying on programmatic API as suggested for SSR or vue-router's own documentation. In case of the latter link, the remarks there are using phrases like "optionally provide", "you can omit" and "return a Promise, if supprted" ... sounds quite open-minded with lots of conditionals trying to express interest in different possible use cases. However, it should present a big red box promoting the imminent need for handling router issues, mostly in context of SSR or VuePress, but eventually with any application.

  • The issue is obviously due to router.push() changing its API in a non-backward-compatible way when it starts throwing exceptions. As given in documentation linked before, this change started in 3.1 which is a minor revision and should be backward-compatible. API reference and documentation on programmatic navigation are indicating support for either providing callbacks or accepting promise returned. However, this documentation is still ambivalent for it's covering a third case:

    router.push(location, onComplete?, onAbort?)
    router.push(location).then(onComplete).catch(onAbort)
    

    The first signature indicates opportunity to use push() without any callback and without handling a promise returned. From a technical point of view this isn't possible for sure. However, you could add support for some options here or in router construction to adjust this behaviour.

    Eventually, one eligible use case of "fire-n-forget" isn't included with this API. I don't know if it has been included properly before. Requiring to handle outcome of every intended change of route is a limitation probably causing unnecessary code in several cases. This is something new to me in context of VueJS for it is mostly favourable for its highly concise syntax. Otherwise I could stick with Angular or even Java and build huge non-DRY applications for ages ...

    You as a visitor might stumble over this issue in context of an existing software just like me. If you don't get any support from either team you can always rely on the power of Javascript by simply patching/hacking original push() method of router instance. Only requirement: you need access on created router instance.

    const originalPush = router.push;
    router.push = function( ...args ) {
    	return originalPush.call( this, ...args ).catch( error => {
    		if ( error ) {
    			console.warn( `consumed router exception: ${error}` );
    		} else {
    			console.warn( `consumed unknown router exception ${new Error().stack.replace( /^[\s\S]+?at/, "at" )}` );
    		}
    	} );
    };

    This isn't a solution. It isn't clean code either. But it's fixing the issue at hand.

@posva
Copy link
Member

posva commented Sep 19, 2020

I checked your repros and the issue you opened on vuepress. Here is an explanation of the whole thing as well as a way to have the behavior that exists in Vue Router 4 #2881 (comment).
The reproduction using VuePress seems to have a different issue, not related (or directly related) to the Router. It's a ReferenceError when bundling on SSR.

I haven't even taken long to answer, it was one week. We were busy releasing Vue 3 and synchronizing things, but I don't have to justify anything to you anyway. The problem is that your comments are lacking basic empathy towards me as a maintainer and it's simply not worth my mental health to deal with that kind of negative comments just to send you the existing resources as I did above.
I hope you take this into account when interacting with open source maintainers in the future.

@vuejs vuejs locked as spam and limited conversation to collaborators Sep 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants