Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle Error in RxJs flatMap stream and continue processing

Tags:

angular

rxjs

I am using RxJs in an Angular 2 application to fetch data from an API for multiple pages in parallel and save any failed requests for future re-try.

To do so, I want to catch errors generated by flatMap-ing http get requests (code below) and continue with further stream processing. In case of error, my current solution causes stream to discontinue.

Rx.Observable.range(1, 5)
   .flatMap(pageNo => {
              params.set('page', ''+pageNo);
              return this.http.get(this.API_GET, params)
                        .catch( (err) => {
                                  //save request
                                  return Rx.Observable.throw(new Error('http failed')); 
                          });
    })
    .map((res) => res.json());  

Let's say in above example, HTTP request for page 2 and 3 fails. I want to handle error (save failed request later retry) for both these request and let other requests continue and get mapped to json().

I tried using .onErrorResumeNext instead of catch, but I am unable to make this work.

like image 229
Aditya Jain Avatar asked Jan 30 '17 21:01

Aditya Jain


People also ask

Is FlatMap deprecated in RxJs?

If multiple requests come in at once then they will all make a request to get the token. To avoid that I share an observable so that the result for getting the token is shared and that only one request is made to get the token. The problem is that flatMap is deprecated and replacing it with mergeMap won't work either.

How do you catch errors in switchMap?

Good Error Handling Always put the “catchError” operator inside a switchMap (or similar) so that it only ends the API call stream and then returns the stream to the switchMap, which continues the Observable.

What is FlatMap in RxJs?

The FlatMap operator transforms an Observable by applying a function that you specify to each item emitted by the source Observable, where that function returns an Observable that itself emits items. FlatMap then merges the emissions of these resulting Observables, emitting these merged results as its own sequence.

How do you perform error handling in observable in angular?

Angular CatchError is an RxJs Operator. We can use it to handle the errors thrown by the Angular Observable. Like all other RxJs operators, the CatchError also takes an observable as input and returns an observable (or throws an error).


1 Answers

Inside your catch, don't return an Observable.throw, then it should continue the stream as desired.

If you want to propagate the information to the outer stream, you could use an return Observable.of("Error: Foo.Bar"); for example.

Or log the error inside the catch and return an Observable.empty() to have the outer stream basically ignore the error.

In other words, just chain this:

.catch(error => Rx.Observable.of(error));

const stream$ = Rx.Observable.range(1, 5)
    .flatMap(num => {
      return simulateRest(num)
             .catch(error => {
                 console.error(error);
                 return Rx.Observable.empty();
             });
      });
             
stream$.subscribe(console.log);

// mocking-fn for simulating an error
function simulateRest(num) {
    if (num === 2) {
        return Rx.Observable.throw("Error for request: " + num);
    }
  
    return Rx.Observable.of("Result: " + num);
}
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
like image 194
olsn Avatar answered Oct 04 '22 06:10

olsn