Search code examples
angularangular-routerangular-errorhandler

Angular - Navigation in ErrorHandler only works with zone.run()


I implemented a global error handler in angular (version 5.2.0) for all unhandled exceptions.

The global error handler looks like this:

import { Router } from '@angular/router';
import { ErrorHandler, Injectable, Injector, NgZone } from '@angular/core';
import { LoggingService } from '../services/logging.service';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {

  private router: Router;

  constructor(injector: Injector, private zone: NgZone, private loggingService: LoggingService) {
    setTimeout(() => {
      this.router = injector.get(Router);
    });
  }

  handleError(error) {
    this.loggingService.logErrorToApi(error);
    this.zone.run(() => this.router.navigate(['/error']));
  }
}

The routing only works if I have the call this.zone.run(...). If I remove this call the routing only adds the route error to the URL and doesn't display the component. The ngOnInit isn't called either.

If I have to use such a "hack" to get my routing to work to me it seems that I have a misconfiguration somewhere in my application.

Has someone and idea what I need to change to get it running without the zone call?


My routing:

const appRoutes: Routes = [
  {
    path: 'error',
    component: ErrorComponent
  },
  {
    path: '',
    component: HomeComponent,
    canActivate: [CookieGuard]
  },
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FooterComponent,
    HomeComponent,
    PageNotFoundComponent,
    ErrorComponent
  ],
  imports: [
    RouterModule.forRoot(appRoutes, { enableTracing: !environment.production }),
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    HttpClientModule,
    HttpClientXsrfModule,
  ],
  providers: [
    { provide: ErrorHandler, useClass: GlobalErrorHandler },
    ApiHttpClientService,
    AppSettingsService,
    CookieGuard,
    LoggingService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Here is my error component that I call:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'error',
  templateUrl: './error.component.html',
  styleUrls: ['./error.component.scss']
})
export class ErrorComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }
}

Solution

  • I found the issue myself after removing every service and module from my application and adding them back one by one until the routing broke again. The module BrowserAnimationsModule causes the problem.

    There is also an open issue on GitHub => https://github.com/angular/angular/issues/20290