Global handling exception in WPF app with Caliburn.Micro
Asked Answered
H

1

6

Hi I try implement solution from this site im my WPF app for global exception handling.

http://www.codeproject.com/Articles/90866/Unhandled-Exception-Handler-For-WPF-Applications.aspx

I use Caliburn Micro as MVVM framework. Service I have in external assembly and it is injected in view model class with MEF.

Here is my implementation for global exception handling in WPF app.

App.xaml

         DispatcherUnhandledException="Application_DispatcherUnhandledException"
         Startup="Application_Startup"

App class:

public partial class App : Application
{
    private IMessageBox _msgBox = new MessageBoxes.MessageBoxes();

    public bool DoHandle { get; set; }

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

    private void Application_DispatcherUnhandledException(object sender,
                           System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        if (DoHandle)
        {
            _msgBox.ShowException(e.Exception);
             e.Handled = true;
        }
        else
        {
            _msgBox.ShowException(e.Exception);
            e.Handled = false;
        }
    }


    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        var ex = e.ExceptionObject as Exception;
        _msgBox.ShowException(ex);
    }


}

Service method from external assembly:

    public void ServiceLogOn()
    {
        try
        {

        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

This service method is call in view model class for example on button click event:

    [Export(typeof(ILogOnViewModel))]
    public class LogOnViewModel : Screen, ILogOnViewModel
    {
        public void LogOn()
        {
            _service.ServiceLogOn();
        }
    }
  1. I run WPF app in Visual Studio and produce exception with message "Bad credentials" in ServiceLogOn method.

    I expect that I see the message box with the exception.

    But Visual Studio stop debuging app and show exception in service method in service project.

  2. So I try run WPF from exe file and produce same exception in ServiceLogOn method.

    I get this error:

    Exception has been throw by target of an invocation.

Any exception from view model class is not handled in methods:

  • Application_DispatcherUnhandledException
  • or CurrentDomain_UnhandledException.

in App class.

What I do bad?

EDITED with Simon Fox’s answer.

I try implement in MEF bootstraper advice of Simon Fox’s, but I still something do wrong. I move handle logic for exception to OnUnhandledException method in bootstraper class.

Here is my code from bootstraper class:

 public class MefBootStrapper : Bootstrapper<IShellViewModel>
    { 
//...
    private IMessageBox _msgBox = new MessageBoxes.MessageBoxes();

    public bool DoHandle { get; set; }

    protected override void OnUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        if (DoHandle)
        {
            _msgBox.ShowException(e.Exception);
            e.Handled = true;
        }
        else
        {
            _msgBox.ShowException(e.Exception);
            e.Handled = false;
        }

    }
//...
    }

I bind some method from view model on button and throw new exception. Something like this:

public void LogOn()
{
    throw new ArgumentException("Bad argument");
}

But result is sam, I test app out of Visual Studio and get this exception.

Exception has been throw by target of an invocation.

Hacksaw answered 3/2, 2011 at 13:46 Comment(5)
Does the Exception have an InnerException, if so what is it? Can you post the StackTrace contained in the exception?Cannibalize
Hi Simon, Inner exception is null, if I check in Visual Studio, the code in method OnUnhandledException is note executed.Hacksaw
Simon I make simple sample, if you want you can try ut. Here is it:cid-042424ddb4d5fcbf.office.live.com/self.aspx/MSDN/…Hacksaw
the sample you provided works fine for me. If you run the sample from visual studio without debugging (Ctrl+F5) you should get the desired result. The other exception is only displayed when the debugger is attached and if you continue execution you will eventually get to the OnUnhandledException overrideCannibalize
Thank, Simon, I have problem with Visual Studio :)Hacksaw
C
16

Caliburn.Micro has built in support for hooking unhandled exceptions. The Bootstrapper class (which every Caliburn project requires) sets this up for you and provides the virtual OnUnhandledException method.

In your custom BootStrapper you must override OnUnhandledException to perform any custom actions for unhandled exceptions in your app. Note that you will most likely have to marshal actions such as displaying a message box to the UI thread (Caliburn enables this easily via Execute.OnUIThread).

You may also have an issue in the way your service moves exceptions to the client, but without any details of how the service is implemented/hosted/etc I cannot help. Are you using WCF to do SOAP? Are you using FaultContracts?

Cannibalize answered 9/2, 2011 at 20:43 Comment(2)
Hi Simon, I am not using SOAP or REST Web Services, it is only HTTP POST/GET communication, no SOAP /JSON. I edited my question, see it.Hacksaw
This answer is right. However it didn't work for me since the exception wasn't thrown from the UI thread. I was using Tasks so I derived from this answer suggesting the use of Task.ContinueWithValina

© 2022 - 2024 — McMap. All rights reserved.