Reputation: 183
I have a pretty simple http call happening. Upon error I want the request to retry 3 times with a three second delay between retries. I have worked out a solution that is close:
return this.http.put<string>(URL,
value).retryWhen(err => {
return err
.delay(3000)
.take(3)
.concat(Observable.throw("error occurred"));
})
.catch(err => this.handleHttpError(err)) ;
The client retries three times like I expect. However, I don't know how to throw the final error in such a way that my error handler (which normally expects an HttpResponse argument) can process the error.
Once I have taken(3) how can I get the final error, and convert it to an HttpResponse to send to my handler? Or am I looking at this the wrong way?
I need to know, at the end of the day, the HttpResponse that accompanied the error(s). When I throw the err from the retryWhen at the concat function that doesn't seem to accomplish it.
I am betting this is a pretty common thing to do, but being newer to Angular 5 and react I think I am just missing the boat.
Upvotes: 0
Views: 2435
Reputation: 183
For anyone who runs into this, I was able to capture the httpErrorResponse by slightly changing the return:
first I added a local var
let httpError: HttpErrorResponse = null;
then I modified the return:
return error
.do(err => {if (err instanceof HttpErrorResponse) {httpError = err; }})
.delay(3000)
.take(5)
.concat(Observable.throw(error));
})
this allows me to cache the last http error response. I then look for this in the catch and work accordingly. Seems to be working just fine.
Upvotes: -1
Reputation: 96959
You can use concatMap
to count how many times you've tried to resubscribe and according to that send next
or error
notifications (this means re-throwing the error in the inner observable that is propagated further).
Observable.throw(42)
.retryWhen(err => err
.do(console.info) // remove, prints 42
.delay(3000)
.concatMap((error, index) => {
if (index === 2) {
return Observable.throw("error occurred"); // or Observable.throw(error);
}
return Observable.of(null);
})
)
// .catch(err => handleHttpError(err))
.subscribe(
v => console.log('next', v), // not called
e => console.log('error handler', e),
);
This prints the following output:
42
42
42
error handler: error occurred
See live demo: https://stackblitz.com/edit/rxjs5-jt5ald
Upvotes: 4