2023-04-19

Angular: why doesn't my app component detect observable changes pushed by my error handler?

My idea is that I'll have a global error handler service that catches all uncaught errors and provides the error as an observable to any interested components. I want to subscribe to the observable from my app component, and if there's an error, show an error page.

//error-service.ts

@Injectable({
  providedIn: 'root',
})
export class ErrorService implements ErrorHandler {
  error = new Subject<Error>();

  handleError(error: any): void {
    console.error('ERROR', error);
    this.error.next(error);
  }
}

This ErrorService is registered as the global error handler for the app module.

//app.module.ts

@NgModule({
  providers: [{ provide: ErrorHandler, useClass: ErrorService }],
  //...
})
export class AppModule {}

The ErrorService is injected into the app component.

//app.component.ts

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  error = this.errorService.error;

  constructor(private errorService: ErrorService) {}
}

The app component template displays the error page if there's an error, otherwise displays the router outlet.

//app.component.html

<app-error-page *ngIf="error | async"></app-error-page>
<router-outlet *ngIf="!(error | async)"></router-outlet>

However, it's not working. The global error handler is indeed catching the uncaught errors, so it's registered properly and the handleError() method is running, however the app component isn't re-rendering its template.

If I push a new error to the ErrorService.error subject from another component, rather than from the global error handler (ErrorService.handleError()), then it does work -- the app component re-renders its template and shows the error page.



No comments:

Post a Comment