Angular 5 two failed http call only trigger catchError once


Angular 5 two failed http call only trigger catchError once



I am using Observable.zip to handle several observables in parallel.


Observable.zip


Observable.zip(observable1, observable2).subscribe(([res1, res2]) => doStuff())



Here observable1 and observable2 are http requests, and I have an interceptor catching errors.


observable1


observable2


import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse,
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { catchError } from 'rxjs/operators';
import { LoggerService } from '../../core/log/logger.service';

@Injectable()
export class ErrorHandlerInterceptor implements HttpInterceptor {
constructor(private logger: LoggerService) { }

intercept(req: HttpRequest<any>, next: HttpHandler) {
return next.handle(req)
.pipe(
catchError(this.handleError())
);
}

private handleError() {
return (err: any) => {
if (err instanceof HttpErrorResponse) {
this.logger.error(`status: ${err.status}, ${err.statusText}`);
}
return Observable.throw(err);
}
}
}



In my case, I did not launch the server, so two http calls both failed, but I found that handleError only triggered once.


handleError



Is there any fix?





Interceptors are called for each request so if you know that catchError is called just once the problem is going to be somewhere else.
– martin
Jun 29 at 10:44


catchError




1 Answer
1



You are passing your observables as arguments to zip. Please note zip subscribes to the passed observables one by one and in the order in which they are passed. If first subscription ends in error quick enough before second observable is subscribed, second subscription will not happen anymore. Therefore only one http call is triggered thus your interceptor is intercepting only once.


zip


zip



I learned the above mentioned behavior of zip, in this answer by cartant.


zip





thanks for explanation. Is there any fix then?
– Z'Terence
Jun 30 at 2:20





Oh, import { async } from 'rxjs/scheduler/async'; + Observable.throw(err, async) works well!
– Z'Terence
Jun 30 at 2:33


import { async } from 'rxjs/scheduler/async';


Observable.throw(err, async)






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Opening a url is failing in Swift

Export result set on Dbeaver to CSV