ReactiveUI exception handling

烂漫一生 提交于 2019-11-29 21:55:31

You're understanding ThrownExceptions, but it's on the wrong guy, _theAnswer.ThrownExceptions will receive the Exception. But the tricky part, is now that button doesn't work any more - once an Observable ends OnError, it's done for good.

You end up having to do a few backflips here, something like:

static IObservable<int?> AnswerCalculator()

CalculateTheAnswer
    .SelectMany(_ => AnswerCalculator())
    .Catch(Observable.Return(null))
    .Where(x => x != null)
    .Select(x => x.Value)
    .ToProperty(this, x => x.TheAnswer);

In this case, ReactiveAsyncCommand is much easier, since a new IObservable is created for every invocation, so you'd do:

// ReactiveAsyncCommand handles exceptions thrown for you
CalculateTheAnswer.RegisterAsyncTask(_ => AnswerCalculator())
    .ToProperty(this, x => x.TheAnswer);

CalculateTheAnswer.ThrownExceptions.Subscribe(ex => MessageBox.Show("Aieeeee"));

How to use UserError

So, UserError is like an exception intended to be thrown at a user (i.e. it contains friendly text, not programmer text)

To use UserError, you have to do two things - first, change your ThrownExceptions:

CalculateTheAnswer.ThrownExceptions
    .SelectMany(ex => UserError.Throw("Something bad happened", ex))
    .Subscribe(result => /* Decide what to do here, either nothing or retry */);

And in your View code-behind, call `RegisterHandler":

UserError.RegisterHandler(err => {
    MessageBox.Show(err.ErrorMessage);

    // This is what the ViewModel should do in response to the user's decision
    return Observable.Return(RecoveryOptionResult.CancelOperation);
});

The cool part, is that this makes error dialogs testable - in a unit test:

var fixture = new MainWindowViewModel();
bool errorCalled;

using (UserError.OverrideHandlersForTesting(_ => { errorCalled = true; return RecoveryOptionResult.CancelOperation })) { 
    CalculateTheAnswer.Execute(null);
}

Assert.True(errorCalled);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!