Reputation: 4380
I am looking to create an observable that subscribes to an input source but then only keeps the error message (i.e. ignores elements and completion messages until someone calls Dispose).
Basically I am looking for something like Observable.IgnoreElements but that would work more like Observable.Never.
The problem is that IgnoreElements leaves both termination messages (success and error). I only want to leave the error notification and ignore when a sequence successfully terminates. The Never method does this, but only generates an observable sequence, you cannot create it from another sequence.
Upvotes: 1
Views: 333
Reputation: 7029
If I understand your question then I think this will work.
given an observable named source
:
source.Materialize().Where(x => x.Kind == NotificationKind.OnError);
Upvotes: 1
Reputation: 79441
If what you want is to ignore all updates except for a single exception, if it occurs, then you can do this:
public static IObservable<T> OnlyError<T>(this IObservable<T> source)
{
return Observable.Create<T>(
observer => source.Subscribe(
value => { },
observer.OnError));
}
(The rest of the answer is no longer relevant because the question was changed.)
If you want to have multiple exceptions in a single sequence, the solution is a little more involved.
The implicit contract for IObserver<T>
is that it will be called according to this pattern:
OnNext* [OnError|OnCompleted]
That is, OnError
can be called at most once, and it ends the sequence. See the following excerpt from Observer Design Pattern Best Practices:
Once the provider calls the
OnError
orIObserver<T>.OnCompleted
method, there should be no further notifications, . . .
If you want to have a sequence that can have multiple "errors," define something like this:
interface ITry<T>
{
bool HasValue { get; }
T Value { get; }
Exception Error { get; }
}
And then use it like this:
IObservable<ITry<T>>
Keep IObserver<T>.OnError(Exception)
meaning something went wrong with the sequence itself, not with the items in the sequence.
Upvotes: 3
Reputation: 4380
Turns out there is an obvious solution... simply concatenate to Never, like this:
IObservable<TSource> Never<TSource>(IObservable<TSource> source)
{
return source.IgnoreElements().Concat(Observable.Never<TSource>());
}
Upvotes: 2