1

wondering how to bubble up errors from observable to subscriber’s err function without terminating the stream

for example, making http calls, when the result is a 404 or any other error i catch and throw error in stream. This causes stream to terminate and enter err function block in subscriber

However, is there a way to catch and keep stream open and pass on value to error block in the subscriber. This is to deal with the said 404 error in the subscribers and not in stream. For doing things like error handling and UI changes based on error.

UPDATE WITH CODE: I have a subscriber like so:

this.blahService.getSomething(id)
  .subscribe((response: Response) =>{

      this.cancelBtnText= 'Cancelled';
      this.canCancel = false;


    },
    err =>{
      console.log('ERRROR:::', err);
    });

and Subject like so:

return this.http.get(this.config.apiEndpointUrl, this.options)
  .map((r: Response) => <blah>r.json())
  .catch((error: any) => {
    console.error('A friendly error occurred', error);
    return Observable.throw(error.message || error);
  });

on http errors this will cause catch function to be called. However, when i throw error this terminates stream and all its subscribers, so the next time the event comes around to call service my subscriber is no longer listening to it and is completely unsubscribed, and therefore, no information is ever sent back to subscribe.

This changes when i change the throw to a .empty(), in the service, since this does not terminate stream but now the error function in subscriber is no longer called.

britztopher
  • 1,214
  • 2
  • 16
  • 26
  • 1
    A `http.get` is a one-time-stream, which will `complete` after one emission anyways - did you miss some code maybe? – olsn Mar 14 '17 at 18:51
  • Why do you return `Observable.throw()` if you don't want the stream to end? This is quite similar to not having a `catch()`. – Günter Zöchbauer Mar 14 '17 at 18:55
  • 1
    Maybe this answer helps you: http://stackoverflow.com/questions/41827371/how-do-i-throw-an-error-on-a-behaviour-subject-and-continue-the-stream/41828984#41828984 ? – olsn Mar 14 '17 at 18:58
  • I think i am thinking about this all wrong. I have a subscriber that is listening when a class is instatiated. Since this subscriber is the only one for the class, when an error emitted it cancelled the stream and all of its subscribers. Therefore all subsequent calls to service arent being fulfilled since subscriber is no longer subscribed. – britztopher Mar 14 '17 at 19:13

1 Answers1

0

I've added this code to clarify how subscriptions and error handling actually works.

The subscription (or pipeline) would remain intact waiting (listening) for your next http request by default, even if there was an error.

If you assign the subscription to a variable, you can unsubscribe to it.. It's NOT a recommended practice...

This use case is entirely hypothetical, but shows how you can stop subscribing via code.

The default RxJS Subject is another way to stop on error..

Subjects Are Not Reusable: In RxJS, Subjects cannot be reused. That is to say, when a Subject completes or errors, it can no longer be used. If you try to next on a Subject that is closed due to it’s complete or error method being called, it will silently ignore the notification. If you want the Subject to loudly and angrily error when you next to it after it’s done being useful, you can call unsubscribe directly on the subject instance itself.

import { Subscription } from "rxjs/Subscription";
...
export myComponent implements ngOnInit {
  sub: Subscription;
  records : DomainClz[];


  constructor(private domainService:DomainService) {}

  onInit() {
     // assumes getRecords returns Observable<DomainClz[]>
     // ie it chains map((resp:Response )to resp.json()) to http.get()
     this.sub = this.domainService.getRecords().
       subscribe(records => { this.records = records) },
                 error =>   { console.error(error)    }
       );
  }

  cancel() {
    this.sub.unsubscribe()
  }
}
JGFMK
  • 8,425
  • 4
  • 58
  • 92