Reputation: 6216
The following code throws an error in the iterator (on purpose for testing). As you can see, the subscription easily gets hold of the exception using the onError parameter of the Subscribe method, but what I can't seem to work out is how the finally method could test/get hold of the exception (and therefore modify follow-up behaviour depending on the outcome)
static void Main(string[] args)
{
// pseudo sequence
var sequence = Observable.GenerateWithTime(
(double)0,
i => i < 10,
i => i += 0.5,
i => {
if(i < 6) return i;
throw new InvalidOperationException();
},
i => TimeSpan.FromSeconds(1)
).Timestamp().Finally(() => Console.WriteLine("finally!"));
using (
sequence.Subscribe(x =>
{
Console.WriteLine(x);
},
err => Console.WriteLine(err.ToString()) // Write error to console
)
)
{
Console.ReadLine();
}
Console.ReadLine();
}
Note: this code is for demo purposes only, but it does work :)
The following modifications to the demo above allowed the desired behaviour - thanks to James Hay.
static void Main(string[] args)
{
bool errored = false;
var sequence = Observable.GenerateWithTime(
(double)0,
i => i < 10,
i => i += 0.5,
i =>
{
if (i < 6) return i;
throw new InvalidOperationException();
},
i => TimeSpan.FromSeconds(1)
).Catch(
new Func<Exception, IObservable<double>>(x => {
errored = true;
return Observable.Return((double)0);
})
).Timestamp().Finally(() => Console.WriteLine("finally!" + (errored?"(errored)":"")));
using (
sequence.Subscribe(objects =>
{
Console.WriteLine(objects);
},
err => Console.WriteLine(err.ToString())
)
)
{
Console.ReadLine();
}
Console.ReadLine();
}
Upvotes: 2
Views: 364
Reputation: 12700
Finally
will happen after an error occurs OR the sequence completes. So there may not be an error when execution hits the Finally operator.
If you want something to happen within the sequence when the error is thrown look into the Catch
operator.
So you could add a side effect and re-throw the error:
.Catch(ex =>
{
//Add a side effect here
return Observable.Throw(ex);
})
Or you could just handle the error and continue on through the sequence in some way:
.Catch(ex => Observable.Return("Some continue on error observable")));
Upvotes: 4