Reputation: 885
I have simple user control with a ViewModel and a ReactiveCommand CheckForUpdates
which runs in background and may throw. This command is explicitly executed in ViewModel's WhenActivated
method. All I want to achieve is to catch the exception and log it in ViewModel, and additionally show Message Box to the user. The problem is, when I add Catch
, then ThrownExceptions
doesn't return anything and the MessageBox is not shown. When I remove Catch
, the application crashes... I don't know how to do this properly??
public partial class SettingsDialog : SettingsDialogBase, IDialog
{
public SettingsDialog()
{
InitializeComponent();
this.WhenActivated((CompositeDisposable d) =>
{
ViewModel
.CheckForUpdates
.ThrownExceptions
.Subscribe(ex =>
{
MessageBoxHelper.ShowError(ex); // doesn't fire when `Catch` is present in ViewModel
})
.DisposeWith(d);
});
}
}
ViewModel:
public ReactiveCommand<Unit, ApplicationUpdateInfo> CheckForUpdates { get; set; }
public SettingsDialogViewModel(IApplicationUpdateService updateService)
{
CheckForUpdates = ReactiveCommand.CreateFromTask(async () =>
{
return await CheckForUpdatesAsync();
});
this.WhenActivated((CompositeDisposable d) =>
{
CheckForUpdates
.Execute()
.Catch(Observable.Return(new ApplicationUpdateInfo())) // crashes the app if removed
.Subscribe()
.DisposeWith(d);
});
}
private async Task<ApplicationUpdateInfo> CheckForUpdatesAsync()
{
throw new Exception("Error");
}
Upvotes: 0
Views: 384
Reputation: 169420
You should subscribe to ThrownExceptions
before the exception is thrown.
You typically do this in the constructor of the view model:
CheckForUpdates.ThrownExceptions.Subscribe(ex => ...);
If you want to subscribe to ThrownExceptions
in the view, you need to do it before the view model throws, e.g.:
var subscription = ViewModel?.
CheckForUpdates.
ThrownExceptions.
Subscribe(ex => MessageBoxHelper.ShowError(ex));
this.WhenActivated((CompositeDisposable d) =>
subscription.DisposeWith(d));
Upvotes: 1