Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subscriber should not stop on error in observable

I am struggling with a subscriber, which automatically unsubscribe itself on error:

observable
  .subscribe(
    (data) => {
      // some logic encountering an error during execution
      // comparable to throw new Error()
    }
  )

I can prevent it with using try / catch:

observable
  .subscribe(
    (data) => try { 
        // some logic encountering an error during execution
        // comparable to throw new Error()
      } catch(e) {
      }
  )

But it feels like a work around.

I have dived into the source of Subscriber and SafeSubscriber, which automatically call unsubscribe on error:

  private __tryOrUnsub(fn: Function, value?: any): void {
    try {
      fn.call(this._context, value);
    } catch (err) {
      this.unsubscribe();
      throw err;
    }
  }

Is the only way to prevent this behavior to implement an own Subscriber or using try / catch?

like image 820
CSchulz Avatar asked Jul 08 '17 13:07

CSchulz


People also ask

How do you handle observable errors?

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.

Does observable complete on error?

A well-behaved Observable will call an Observer's complete() method exactly once or the Observer's error(err) method exactly once, as the last notification delivered.

What happens if you don't unsubscribe from an observable?

As you probably know when you subscribe to an observable or event in JavaScript, you usually need to unsubscribe at a certain point to release memory in the system. Otherwise, you will have a memory leak. A memory leak occurs when a section of memory that is no longer being…

Which RxJS operator can be chained to an observable to handle errors?

The catchError operator takes as input an Observable that might error out, and starts emitting the values of the input Observable in its output Observable.


1 Answers

That's correct behavior. You can use the catch() operator to subscribe to the same source Observable again (or a different one on error).

source
  .catch(err => Observable.of(null))
  .subscribe(...);

This will just return null in the next handler instead of the original error.

Also note that any exception is rethrown if the subscriber doesn't have any error handler.

For example to just avoid throwing an error you could make:

source
  ...
  .subscribe(..., error => {});

However this will always unsubscribe the chain because this is one of the basic principles of Observables. They emit zero or more next notifications and one complete or error notification but never both.

It's hard to tell what problem are you trying to solve where you don't want to unsubscribe, sometimes you can use Subject and only pass it next notifications and ignore the rest...:

const subject = new Subject();
source.subscribe(val => subject.next(val));

subject.subscribe(...);
like image 155
martin Avatar answered Sep 21 '22 11:09

martin