Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJS catch **and** retry an Observable

My use case is to map an Observable to redux actions of success and failure. I make a network call (with a function that gives promise), if it succeeds I have to forward a success action, if it fails than an error action. The Observable itself shall keep going. For all I could search, RxJS do not have a mechanism for this catching the error and retrying the original. I have following solution in my code which I am not happy with:

error$ = new Rx.Subject();

searchResultAction$ = search$
    .flatMap(getSearchResultsPromise)
    .map((resuls) => {
        return {
            type: 'SUCCESS_ACTION',
            payload: {
                results
            }
        }
    })
    .retryWhen((err$) => {
        return err$
            .pluck('query')
            .do(error$.onNext.bind(error$));
    });

searchErrorAction$
    .map((query) => {
        return {
            type: 'ERROR_ACTION',
            payload: {
                query,
                message: 'Error while retrieving data'
            }
        }
    });

action$ = Observable
    .merge(
        searchResultAction$,
        searchErrorAction$
    )
    .doOnError(err => console.error('Ignored error: ', err))
    .retry();

action$.subscribe(dispatch);

i.e I create a subject, and push errors into that subject and create an Observable of error actions from that.

Is there a better alternative of doing this in RxJS that I am missing? Basically I want to emit a notification of what error has occurred, and then continue with whatever the Observable is already doing.

like image 795
bitspook Avatar asked Nov 24 '15 12:11

bitspook


People also ask

How do you catch an error on observable?

Catch errors in the observable stream Another option to catch errors is to use the CatchError Operator. The CatchError Operators catches the error in the observable stream as and when the error happens. This allows us to retry the failed observable or use a replacement observable.

What is retry in RxJS?

RxJS retry() operator is an error-handling operator that returns an observable that mirrors the source observable except for an error.

Does observable complete after error?

In an Observable Execution, zero to infinite Next notifications may be delivered. If either an Error or Complete notification is delivered, then nothing else can be delivered afterwards.

What is CatchError?

RxJS catchError() operator is an error-handling operator used to handle and take care of catching errors on the source observable by returning a new observable or an error.


1 Answers

This would retry failed queries:

var action$ = search$
    .flatMap(value => {
        // create an observable that will execute
        // the query each time it is subscribed
        const query = Rx.Observable.defer(() => getSearchResultsPromise(value));

        // add a retry operation to this query
        return query.retryWhen(errors$ => errors$.do(err => {
            console.log("ignoring error: ", err);
        }));
    })
    .map(payload => ({ type: "SUCCESS_ACTION", payload }));

action$.subscribe(dispatcher);

If you don't want to retry, but just want to notify or ignore errors:

var action$ = search$
    .flatMap(value => {
        // create an observable that will execute
        // the query each time it is subscribed
        const query = Rx.Observable.defer(() => getSearchResultsPromise(value));

        // add a catch clause to "ignore" the error
        return query.catch(err => {
            console.log("ignoring error: ", err);
            return Observable.empty(); // no result for this query
        }));
    })
    .map(payload => ({ type: "SUCCESS_ACTION", payload }));

action$.subscribe(dispatcher);
like image 134
Brandon Avatar answered Oct 30 '22 09:10

Brandon