In RxJS version 5, the following code results in the process being terminated after three iterations of both subscriptions:
var Rx = require("rxjs");
const published$ = Rx.Observable.interval(1000).publish();
published$.subscribe(index => {
console.log(`One: ${index}`);
if (index == 3) throw new Error("ded.");
});
published$.forEach(index => {
console.log(`Two: ${index}`);
});
published$.connect();
However, my understanding was that an error thrown in the next handler would simply unsubscribe that particular subscription, and not cause the underlying observable to terminate. My expected output would be that the "One" subscription would unsubscribe, but the interval would continue to produce results to the "Two" subscription.
This behavior is causing me issues, where I may have multiple subscriptions to an underlying hot observable - yet a single exception thrown on any of those subscriptions causes the underlying observable to completely terminate.
It's especially annoying when I'm in development using hot module reloading, since any programming error in any subscription causes me to have to refresh the entire page to re-start the observable sequences.
Is there a way, without wrapping each of my subscriptions in a try/catch, to have an exception thrown in my next handler to simply unsubscribe that ONE subscription, and not terminate the underlying observable?
------------ EDIT ------------
I've found the behavior that I'm looking for, by setting syncErrorThrowable to true on the subscription object returned by "subscribe". It seems that the only time this is ever set to true in the codebase is via the "do" operator.
Should I take advantage of this field? I feel pretty dirty using it, but on the other hand I find it strange that the "do" operator has different error handling semantics than the "next" subscription handler.
Here's the primary block of code affected by this flag: https://github.com/ReactiveX/RxJS/blob/master/src%2FSubscriber.ts#L132
If it's set to false, this method gets invoked: https://github.com/ReactiveX/RxJS/blob/master/src%2FSubscriber.ts#L179
Whereas if it's set to true, this method is used instead: https://github.com/ReactiveX/RxJS/blob/master/src%2FSubscriber.ts#L188
The difference is that the first method will re-throw the exception back up the callstack, whereas the second one instead propagates the error forward to subsequent subscriptions.
Why does the do operator propagate the error forward, whereas the "next" handler bubbles the error back up? This seems odd to me.