arcrub
arcrub

Reputation: 170

RxJS- Conditionally using RetryWhen operator

I would like to devise a scalable error handling strategy for my Observable-based Firebase requests. To do so, I am trying to create a custom RxJS operator for each type of error (e.g. unauthenticated, internal, you name it). The operators would be stacked after the request as follows:

FirebaseRequestObservable.pipe(
...
handleUnauthenticatedError(),
handleInternalError(),
handleYouNameItError(),
...
)

This works fine if my error handling operators only constitute of a catchError operator, in which case its internal structure can simply be:

source.pipe(
catchError((err) => {
  if (err !== errorThisOperatorShouldHandle) {
   throw err 
   } 
  handleError
 }
))

So that the error trickles down to the next custom operator if it shouldn't be handled by that operator.

The problem comes in when my error handling logic for a certain error involves using retryWhen. I do not know how I could then have the operator conditionally employ retryWhen if it is the right error, and re-throw the error to the next operator if it isn't.

Upvotes: 0

Views: 903

Answers (1)

Mrk Sef
Mrk Sef

Reputation: 8022

They're pretty similar. Here's how I might implement these two:

Handle a specific error.

function handleYouNameItError<T>(): MonoTypeOperatorFunction<T> {

  return catchError(err => {
    if(err !== youNameItError){
      return throwError(() => err);
    }else{
      // handleError
      return EMPTY;
    }
  });

}

Retry a specific error.

function retryYouNameItAnotherError<T>(): MonoTypeOperatorFunction<T> {

  return retryWhen(err$ => err$.pipe(
    tap(err => {
      if(err !== youNameItAnotherError){
        throw err;
      }
    }),
    // Delay 1s between retries
    delay(1000),
    // Only retry 5 times
    take(5),
    // After 5 retries, throw a new error
    concatWith(throwError(() => 
      new YouNameItAnotherErrorFailedAfterRetries()
    ))
  ));

}

Use them as operators :)

FirebaseRequestObservable.pipe(
  ...
  handleYouNameItError(),
  retryYouNameItAnotherError()
  ...
);

Upvotes: 2

Related Questions