My application terminates when an error is thrown in OnNext by an observer when I use ObserveOn(Scheduler.ThreadPool). The only way I have found to
There's a difference between errors in subscription and errors in the observable. A quick test:
var xs = new Subject();
xs.Subscribe(x => { Console.WriteLine(x); if (x % 3 == 0) throw new System.Exception("Error in subscription"); },
ex => Console.WriteLine("Error in source: " + ex.Message));
Run with this and you'll get a nice handled error in the source:
xs.OnNext(1);
xs.OnNext(2);
xs.OnError(new Exception("from source"));
Run with this and you'll get an unhandled error in the subscription:
xs.OnNext(1);
xs.OnNext(2);
xs.OnNext(3);
What your solution has done is take errors in the subscription and make them errors in the source. And you've done this on the original stream, rather than on a per subscription basis. You may or may not have intended to do this, but it's almost certainly wrong.
The 'right' way to do it is to add the error handling you need directly to the subscribing action, which is where it belongs. If you don't want to modify your subscription functions directly, you can use a little helper:
public static Action ActionAndCatch(Action action, Action catchAction)
{
return item =>
{
try { action(item); }
catch (System.Exception e) { catchAction(e); }
};
}
And now to use it, again showing the difference between the different errors:
xs.Subscribe(ActionAndCatch(x => { Console.WriteLine(x); if (x % 3 == 0) throw new System.Exception("Error in subscription"); },
ex => Console.WriteLine("Caught error in subscription: " + ex.Message)),
ex => Console.WriteLine("Error in source: " + ex.Message));
Now we can handle (separately) errors in the source and error in the subscription. Of course, any of these actions can be defined in a method, making the above code as simple as (potentially):
xs.Subscribe(ActionAndCatch(Handler, ExceptionHandler), SourceExceptionHandler);
Edit
In the comments we then started discussing the fact that errors in the subscription are pointing to errors in the stream itself, and you wouldn't want other subscribers on that stream. This is a completely different type of issue. I would be inclined to write an observable Validate extension to handle this scenario:
public static IObservable Validate(this IObservable source, Predicate valid)
{
return Observable.Create(o => {
return source.Subscribe(
x => {
if (valid(x)) o.OnNext(x);
else o.OnError(new Exception("Could not validate: " + x));
}, e => o.OnError(e), () => o.OnCompleted()
);
});
}
Then simple to use, without mixing metaphors (errors only in source):
xs
.Validate(x => x != 3)
.Subscribe(x => Console.WriteLine(x),
ex => Console.WriteLine("Error in source: " + ex.Message));
If you still want suppressed exceptions in Subscribe you should use one of the other discussed methods.