Home > front end >  Error handling best practices - async pipe
Error handling best practices - async pipe

Time:10-22

is there some kind of best practise in async pipe error handling? Is it preferable to handle errors in service(but that means we have to use some kind of global error handling) or it is better in component? What do you guys prefer?

For example in my service i have getter which is then consumed in component:

//service
get loadedEvents(){
 //appStatus emits when selectedMonth is changed
    return this.statusService.appStatus.pipe(                                             
    switchMap(status=>this.getOffers(status.selectedMonth)),         
    shareReplay({refCount:true})); }

getOffers(date:Date){
    return this.httpClient.get(...);
}

//component
events$=this.service.loadedEvents;

Where is it better to catch error? In component or service?

CodePudding user response:

First of all, don't use a getter. This creates a new memory reference everytime (see this)

Instead, use pipeable operators.

loadedEvents = this.statusService
  .appStatus
  .pipe(                                             
    switchMap(status=>this.getOffers(status.selectedMonth)),         
    shareReplay({refCount:true})
  );

Next, for the errors : you can create a structural directive, made to handle the errors when they appear. Something like this : (See it in action)

export class AsyncerrDirective {
  @Input() asyncerr: Observable<any>;
  @Input() asyncerrCatch: any;

  constructor(
    private viewRef: ViewContainerRef,
    private tplRef: TemplateRef<any>
  ) {}

  ngOnInit() {
    console.log(this.asyncerrCatch);

    this.viewRef.clear();

    this.asyncerr.pipe(tap(() => this.viewRef.clear())).subscribe({
      next: (asyncerr) => {
        const ref = this.viewRef.createEmbeddedView(this.tplRef);
        ref.context = { asyncerr, $implicit: asyncerr };
      },
      error: (error) => {
        const ref = this.viewRef.createEmbeddedView(this.tplRef);
        ref.context = { [this.asyncerrCatch]: error };
      },
    });
  }
}
<ng-container *asyncerr="data$ as data; catch: 'error'; let error = error">
  <ng-container *ngIf="error; else dataTpl">
    {{ error }}
  </ng-container>

  <ng-template #dataTpl>
    {{ data | json }}
  </ng-template>
</ng-container>

CodePudding user response:

It depends on your need:

Case 1 - Cath all the errors and show with toaster messages

Yes, in this case, we can catch the error in services and push the error to the toaster message service & component

Case 2 - Showing message inside the component

We need to catch the error in every component

  • Related