PRISM Unhandled exception handling in modules

Topics: Prism v4 - WPF 4
Jan 11, 2012 at 9:09 PM
Edited Jan 11, 2012 at 9:12 PM

Hello experts,

I'm building an application using PRISM, MVVM and Enterprise Library. Currently i'm trying to figure out how to handle unhandled exceptions thrown in my application. For the shell I already found a nice solution that is used in the current StockTraderRI example, it allows to display a message and write to a log using the Enterprise Library logging facilities.

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

#if (DEBUG)
            RunInDebugMode();
#else
            RunInReleaseMode();
#endif
            this.ShutdownMode = ShutdownMode.OnMainWindowClose;
        }

        private static void RunInDebugMode()
        {
            StockTraderRIBootstrapper bootstrapper = new StockTraderRIBootstrapper();
            bootstrapper.Run();
        }

        private static void RunInReleaseMode()
        {
            AppDomain.CurrentDomain.UnhandledException += AppDomainUnhandledException;
            try
            {
                StockTraderRIBootstrapper bootstrapper = new StockTraderRIBootstrapper();
                bootstrapper.Run();
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }

        private static void AppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            HandleException(e.ExceptionObject as Exception);
        }

        private static void HandleException(Exception ex)
        {
            if (ex == null)
                return;

            ExceptionPolicy.HandleException(ex, "Default Policy");
            MessageBox.Show(StockTraderRI.Properties.Resources.UnhandledException);
            Environment.Exit(1);
        }

I added support for handling DispatcherUnhandledException event so that also unhandled wpf ui thread exceptions are logged this way.

Now while this works perfectly for the main/shell project, it doesn't work for modules. If an exception is thrown in, for example, a viewmodel located in a module, it won't be logged. When you think of it, this is actually expected behavior because of the composite nature of modules. My question is how to log these unhandled exceptions throw in modules in a nice way. I was thinking about subscribing to the AppDomain.CurrentDomain.UnhandledException event in the modules Initialize() method and then sending them over via the Event Aggregator. Is this a good idea or would you experts handle this differently?

Many thanks in advance!

 

Jan 11, 2012 at 10:38 PM
Edited Jan 11, 2012 at 10:40 PM

I hope it is ok to answer my own question. I went ahead and started implementing the proposed system. Turned out it didn't work at all. The UnhandledException event wasn't handled in the modules. After testing around with some exceptions at other places it did appear to work. But why wouldn't it work in the two locations I tried before posting this question then?

Test exception #1 [throw new Exception("YOU CANT CATCH ME!!!")] was placed in code that was executed by a background worker. All unhandled exceptions in the DoWork method are caught by the background worker and placed into the RunWorkerCompletedEventArgs.Error property. => Exception is not qualified as unhandled and won't be catched.

Test exception #2 [throw new Exception("TOO FAST FOR YOU")] was placed in code that was swallowed by a RequestNavigate call. More information here: *

The last post contains a blog post about this issue together with a possible solution.

So all is fine now, sorry to have bothered you. On the plus side I learned a lot!

* cant post links here but the title of the page (located at this site!) is RequestNavigate swallowing exceptions and won't call callback