Reputation: 1089
Suppose there is a Http request observable that errored, we can just retry it. But I also want the UI to inform the user that this resource failed to load. What is the best architecture?
(3 and 4 can be achieved by shareReplay({bufferSize: 1, refCount: true})
)
I think it's best to pass an error message to the downstream observer while keeping retrying the source. It causes minimum changes to the architecture. But I didn't see a way I can do it with Rxjs, because
retry()
always intercepts the error. If you materialze the error, then retry()
won't retry. If not, then no error will propagate to the downstream.catchError()
without rethrowing will always complete the stream.Although let the UI observer tap(,,onError)
and retry()
can satisfy this need, but I think it is dangerous to let the UI take this responsibility. And multiple UI observer means a LOT of duplicated retries.
Upvotes: 3
Views: 1934
Reputation: 1089
Well, I seem to have accidentally find the answer while browsing through the documentations.
It starts with the usage of the second parameter of the catchError
. According to the documentation, retry
is implemented by catchError
. And we can express more logic with the lower-level catchError
.
So it's just
catchError((err, caught) => {
return timer(RETRY_DELAY_TIME).pipe(
mergeMap(() => caught)
startWith(err)
);
})
It retries the observable, meanwhile sending error messages to the downstream observers. So the downstream is aware of the connection error, and can expect to receive retried values.
Upvotes: 3
Reputation: 3571
It sounds like you're looking for something akin to an NgRx side effect. You can encase it all in an outer Observable, piping the error handler to the inner Observable (your HTTP call), something like this:
const myObs$ = fromEvent('place event that triggers call here').pipe(
// just one example, you can trigger this as you please
switchMap(() => this.myHttpService.getResource().pipe(
catchError(err => handleAndRethrowError()),
retry(3)
),
shareReplay()
);
This way, if the request throws an error, it is retried 3 times (with error handling in the catchError
block, and even if it fully errors out, the outer Observable is still alive. Does that look like it makes sense?
Upvotes: 1