Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular - How to implement Exception Handling on component level

While working inside Angular (Angular 4, 5), if a component raises Error (TypeError or null or undefined error or so), whole application breaks onward.

How can we deal with this, to catch errors on component level and possibly show a fallback UI, like React16 does using Error Boundaries.

like image 271
abdul-wahab Avatar asked Dec 20 '25 07:12

abdul-wahab


2 Answers

I would approach it by handling the error at Component level and have a service that listens to any errors happening at Component or Service level. Ex:

  1. Throw the error from the service
  2. catch the error in component
  3. Handle the error, process it and send the Error event with details to ErrorService.
  4. You can have a app level component "errorBannerComponent" which takes input from ErrorService and paint your UI.
  5. As soon as the error is received in ErrorService, The errorBannerComponent should display the error on screen.

Hope it helps.

Also By default, Angular comes with its own ErrorHandler that intercepts all the Errors that happen in our app and logs them to the console, preventing the app from crashing. We can modify this default behavior by creating a new class that implements the ErrorHandler:

You can find more details and example here:

like image 173
nircraft Avatar answered Dec 21 '25 22:12

nircraft


As the proposed solutions are rather dull. I tried to recreate it myself. The easiest solution would be to provide a module scoped custom ErrorHandler class. Thanks to this, you could even create a multiple different ErrorBoundaries.

My proposed solution can be seen here: https://stackblitz.com/edit/angular-ivy-brb143?file=src/app/widget/widget.module.ts

What is really important for this solution to work (atleast it didn't work otherwise for me). Was to provide the custom error handler as a part of a module rather than a component directly.

The important bits from the solutions:

module:

/**
 * This is really imporant as this allows us to provide a module scoped ErrorHandler
 */
@NgModule({
  imports: [CommonModule],
  declarations: [WidgetComponent],
  providers: [{ provide: ErrorHandler, useClass: WidgetErrorHandler }],
  exports: [WidgetComponent],
})
export class WidgetModule {}

component where we can throw, and catch error

@Component({
  selector: 'app-widget',
  templateUrl: './widget.component.html',
  styleUrls: ['./widget.component.css'],
})
export class WidgetComponent implements OnInit {
  constructor(@Inject(ErrorHandler) public widgetError: WidgetErrorHandler) {}

  ngOnInit() {
    this.widgetError.isError$.subscribe((error) =>
      console.log('component can act on error: ', error)
    );
  }

  public handleThrowErrorClick(): void {
    throw Error('Button clicked');
  }
}

and the handler iself


@Injectable()
export class WidgetErrorHandler implements ErrorHandler {
  public isError$: Subject<Error | any> = new Subject();

  handleError(error) {
    console.log('Intercepted error', error);
    this.isError$.next(error);
  }
}
like image 29
karoluS Avatar answered Dec 21 '25 23:12

karoluS



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!