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

Router can't navigate when exception occurrs #15946

Closed
zwjohn opened this Issue Apr 13, 2017 · 13 comments

Comments

Projects
None yet
10 participants
@zwjohn

zwjohn commented Apr 13, 2017

I'm submitting a ... (check one with "x")

[V ] bug report => search github for a similar issue or PR before submitting

Current behavior

Router.Navigate fails to navigate when exception occurs
Expected behavior

Router is able to navigate even though application exception occurred
Minimal reproduction of the problem with instructions

I have created a plunker here, you can comment out line 16 of ContactComponent to see the no exception scenario, and enable it to see the error scenario. I purposely created this exception to test out exception navigation, I expect my custom error handler GlobalErrorService is able to navigate the page to ErrorComponent, but that's not happening

https://embed.plnkr.co/HhYYHnqAOHzFAvKc7o58/

What is the motivation / use case for changing the behavior?

Please tell us about your environment:

Windows

  • Angular version: 4.0.2
  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
  • Language: [all | TypeScript X.X | ES6/7 | ES5]

  • Node (for AoT issues): node --version =

@tbosch tbosch added the comp: router label Apr 14, 2017

@alexmbrown

This comment has been minimized.

alexmbrown commented Apr 17, 2017

I've ran into this problem before as well. Some of the work arounds that I've used (1) wrap the router call in a timeout (2) Instead of triggering the router event inside your error handler, implement a service that exposes an EventEmitter. Emit an event when an error occurs and subscribe to it in your root component. When an error is received in your root component trigger the routing event. The EventEmitter is required to be asynchronous for this to work. With a non asynchronous event emitter the router will still fail to route correctly.

@zwjohn

This comment has been minimized.

zwjohn commented Apr 18, 2017

Thank Alex for your recommendation, unfortunately these two approaches don't work when router is crashed base on my test. When there is a template exception on the landing page, the router stuck in activated state and it can't be navigated anymore, I am getting following error even with timeout or eventemitter.
I've updated my plunker to illustrate the issue. https://embed.plnkr.co/HhYYHnqAOHzFAvKc7o58/

"Uncaught (in promise): Error: Cannot activate an already activated outlet
Error: Cannot activate an already activated outlet"

@jonesmac

This comment has been minimized.

jonesmac commented Apr 25, 2017

I would love some thoughts on this. The plunkr is exactly my setup. Navigating once an exception occurs seems impossible at this point.

@andrei-ivanovici

This comment has been minimized.

andrei-ivanovici commented Jul 23, 2017

Any updates on this, guys? This seems like a very big issue to me. I'm having a similar problem. If there are any errors when creating the component that I'm navigating to, the router will just stop working. There is no way to recover besides reloading the app :(

@zoechi

This comment has been minimized.

Contributor

zoechi commented Jul 23, 2017

I wouldn't expect this to be changed. Just ensure your exceptions are handled.

An ugly workaround is to call ApplicationRef.tick() to invoke change detection to get your application back into a working state. This should at most be used to be able to show the user that the application has crashed and that it should be reloaded.

@n00dl3

This comment has been minimized.

n00dl3 commented Sep 20, 2017

I am redirected to the error page when an error occurs but the whole app is fubar, note that ErrorComponent's ngOnInit is not being called :

export class ErrorComponent {
    constructor(){
      console.log("constructed"); // called
    }
     ngOnInit(){
       console.log("init"); // not called
     }
}

you can check on plunkr

I wouldn't expect this to be changed.

@zoechi Why ? That was the exisiting behavior, I had no problem until upgrading from 4.1 to 4.3.

It seems that ApplicationRef.tick() has no impact.

@zoechi

This comment has been minimized.

Contributor

zoechi commented Sep 20, 2017

I had no problem until upgrading from 4.1 to 4.3.

I'm not aware of such changes (doesn't mean they didn't happen, I just didn't run into it).

I guess you just need to invoke change detection to get your app going again.
Just don't assume that it is in a sane state after an unhandled exception.
Showing an error page is risk-free, therefore safe to do with this workaround.

@n00dl3

This comment has been minimized.

n00dl3 commented Sep 20, 2017

When I say "it has no impact" I mean "it does not work".

@zoechi

This comment has been minimized.

Contributor

zoechi commented Sep 20, 2017

@n00dl3

This comment has been minimized.

n00dl3 commented Sep 20, 2017

Yes, thank you, I didn't think to use the zone... silly me !

For future readers :

inside your error handler service (think to inject NgZone) :

this.zone.run(()=>this.router.navigate(["/error"]))
@dbayonacode

This comment has been minimized.

dbayonacode commented Jun 6, 2018

Why zone.run solve the issue... ? A bit of context please ...

@n00dl3

This comment has been minimized.

n00dl3 commented Jun 6, 2018

Because an exception makes you leave angular 's zone. If you figure out why, you can fix the issue and submit a PR 😉.

@JiaLiPassion

This comment has been minimized.

Contributor

JiaLiPassion commented Jun 7, 2018

@dbayonacode , handleError will run outside of angular zone, this is by design, https://github.com/angular/angular/blob/master/packages/core/src/zone/ng_zone.ts#L298

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment