angularobservablehttpclientrxjs5retrywhen

Retrying a http call on receiving a certain http status


I'm trying to catch and retry a 103 Http error status response. The service call returns 103 if the server understood the request and will start processing it but resource is immediately unavailable. What I'd like to do is when I receive 103, I'd like to retry getting the resource after every 5 seconds for up to 5 times and at the end of which I'd like it to timeout and give back 404 error. This is what I have so far

getDoc() {
  return this.getError()
    .retryWhen((errors: any) => {
      return errors.switchMap((sourceError) => {
        console.log(sourceError);
        if (sourceError.status === 103) {
          console.log('status is 103');
          const notFoundError = new HttpErrorResponse({
            status: 404
          });
          return errors.delay(5000).take(5).concat(Observable.throw(notFoundError));
        }
        return Observable.throw(sourceError);
      });
    })
    .toPromise();
}

getError() {
  console.log('getting error');
  return Observable.throw(new HttpErrorResponse({
    status: 103
  }));
}

with getError() function, I am trying to mimic a 103 because the server doesn't send 103 yet. Maybe getError() is not a good representation of httpError response. I wasn't sure how else to reproduce and throw an observable error.

Anyway, this setup doesn't work. It calls getError(), fails and goes all the way up to console.log('status is 103') and after that nothing. Any help is appreciated.


Solution

  • You can use HttpInterceptor.

    @Injectable()
    export class ServiceCallProvider implements HttpInterceptor {
    
    public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
        return next.handle(request).do((event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
            // do stuff with response if you want
          }
        }, (err: any) => {
          if (err instanceof HttpErrorResponse) {
            if (err.status === 103) {
              // handle logic
            }
          }
        });
      }
    }