Leandro Lima
Leandro Lima

Reputation: 5428

How do I catch an error at two different points in RxJS/Angular?

Suppose this Angular 2 snippet:

export class ApiService {
  // do stuff
  request(...): Observable<Response> {
    return this.http.request(...)
      .share()
      .catch((error: any) => {
        let errMsg = 'my error';
        // do more stuff...
        // tried: throw errMsg;
        // tried: return Observable.throw(errMsg);
      });
  }
}

Then:

api.request(...).catch(() => {
  console.log('caught');
  return Observable.from([]);
}).subscribe({
  console.log('everything fine');
});

The next callback passed to subscribe does get called just fine when the request succeeds, but the callback passed to catch doesn't.

I've trying do deal with the error in two different parts of the code that have different responsibilities. I'd like that the error message thrown at the ApiService.request would end up in the second callback so I could further refine my response to the user. I've tried both throw errMsg and returning Observable.throw(errMsg).

The reason why I'm using .share() for the observable is because I don't want the http client to be generating one request per subscriber.

Where am I getting this wrong?

EDIT:

My example above didn't really capture the problem I was having. This second snippet allows for the reproduction of it:

const a = Rx.Observable.create(function(observer){
  observer.error('h');
}).share().catch(err=> {
  console.error('first place',err);
  throw 'err'
})
.subscribe(() => null)
.subscribe(console.log, console.error);

The first subscribe was failing to catch the error (by not having an error handler defined) and breaking the chain to the second subscriber.

Upvotes: 2

Views: 80

Answers (1)

Vamshi
Vamshi

Reputation: 9331

From what I understood you want to catch the error in two places . As per docs you need to use throw . I tried and its working fine for me . Here is the code snippet :

const a = Rx.Observable.create(function(observer){
    observer.error('h');
});

a.catch(err=> {
   console.error('first place',err);
   throw 'err'
}).subscribe(console.log,console.error);

Output

x first place 
x err 

JSBin : https://jsbin.com/jefalazibo/edit?html,js,console

In the component code you dont need to write another catch . subscribe takes three functions as arguments

 subscribe(onSuccess, onError, onComplete);

Documentation : https://github.com/ReactiveX/rxjs/blob/master/src/operator/catch.ts ( check example 3 )

Upvotes: 1

Related Questions