Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global exception handler for MVVM Light application

I'm trying to create a simple global exception handler in a WPF application that is build with the MVVM Light Toolkit, but I'm having a hard time making it work.

The thing is that an exception risen in a view model will not be caught in the App's UnhandledException handler, even though I register a listener for both the Dispatcher and the AppDomain like this:

private void Application_Startup(object sender, StartupEventArgs e)
{
   AppDomain.CurrentDomain.UnhandledException += DomainUnhandledException;
   DispatcherUnhandledException += App_DispatcherUnhandledException;
}

private void DomainUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
   var exception = unhandledExceptionEventArgs.ExceptionObject as Exception;
   ShowExceptionMessage(exception);
}
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
   ShowExceptionMessage(e.Exception);
   e.Handled = true;
}

I found this blog post that describes the problem spot on, with the solution described with this code snipped for view models:

// Throw the exception in the UI thread.
App.Current.RootVisual.Dispatcher.BeginInvoke(() => { throw new MyException(); });

However, I would like all exceptions to bubble up to the global exception handler, not only the ones that I throw myself in the VM.

So the question is: Is it somehow possible to re-throw exceptions from other threads into the UI thread in one place?

Update: Added more detailed code for the App's event handler setup.

like image 487
Anttu Avatar asked May 31 '12 12:05

Anttu


1 Answers

I think I figure this out now.

The problem is due to the fact that WPF suppresses exceptions thrown in a view's databinding, and because my view model is databound to the view's DataContext (through a property in my ViewModelLocator utilizing unity dependency injector) any exceptions in the construction of the view model will be swallowed.

See this SO question for more info.

So I suppose I just have to make sure that nothing important for the application's ability to function correctly should happen in the constructor.

like image 166
Anttu Avatar answered Sep 18 '22 23:09

Anttu