Issue
I am building an angular 5 app where I have 2 interceptors:
- One to retry failed 504 requests
- Another to show error messages to users about failed requests
I want that the second interceptor only gets called when the error is not 504 or when it is 504 and has already been retried by the first interceptor.
I have created a sample with both interceptors: https://stackblitz.com/edit/angular-interceptors-ckbvsb
Hope to get some assistance!
Thanks
UPDATE:
Thanks everyone for your assistance! I have ended up implementing it like this:
@Injectable()
export class I1 implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('intercepted I1');
return next.handle(req)
.retryWhen(error => {
return error
.mergeMap((err, i) => {
if (i > 0) return Observable.throw(err)
if (err instanceof HttpErrorResponse && err.status === 504) { // timeout
return Observable.of(err).delay(5000);
} else {
return Observable.throw({ error: 'No retry', cause: err })
}
})
});
}
}
Solution
Your issue is the order in which you provide the two interceptors. You are providing I1 first and then I2. This means that a request will flow through I1 → I2, but the response will flow through I2 and only then through I1. So just switch the order:
@NgModule({
imports: [BrowserModule, HttpClientModule],
declarations: [AppComponent],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: I2, // <-- I2 first
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: I1, // <-- And only then I1
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule {
}