9

I originally had code to handle DispatcherUnhandledException which would log the error and mark the exception as handled

protected override void OnStartup(StartupEventArgs e)
{
    Dispatcher.UnhandledException += OnDispatcherUnhandledException;
}
...
void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    // Log Error here
    e.Handled = true;
}

I've tried to improve this by covering a wider range of unhandled exceptions

    protected override void OnStartup(StartupEventArgs e)
    {
         AppDomain.CurrentDomain.UnhandledException += (s, ex) =>
         LogUnhandledException((Exception)ex.ExceptionObject, 
        "AppDomain.CurrentDomain.UnhandledException");

         DispatcherUnhandledException += (s, ex) =>
         LogUnhandledException(ex.Exception, 
         "Application.Current.DispatcherUnhandledException");

         TaskScheduler.UnobservedTaskException += (s, ex) =>
         LogUnhandledException(ex.Exception, 
         "TaskScheduler.UnobservedTaskException");
    }

but I cannot handle the exceptions using this event

    private void LogUnhandledException(Exception e, string @event)
    {
      // Log Error here
      e.Handled = true; //Doesn't work
    }

How can I handle all types of exceptions here so the code will attempt to continue?

  • What is `e` in your last code sample? Maybe it's better to path the whole event arguments object into the handler, instead of exception property, the still will be accessible from inside – ASpirin Aug 26 '17 at 20:31
  • Can you specify what you mean by *code will attempt to continue*? In the UI context it's somewhat understandable. Exception was thrown on some event code and the event code will not be continued but the next event will start executing some code of its own. But outside the UI context I don't know what you want to continue exactly. – grek40 Aug 28 '17 at 08:28

1 Answers1

7

Frankly, your entire design is a bad idea, in my opinion. It appears to me that you want to be able to "handle" these exceptions by logging them and letting your program continue executing. But that's an incredibly dangerous approach and definitely not recommended. You should only catch and handle exceptions for which you know in advance what the exception is and what the safe way to handle it is.

To do otherwise is to risk leaving your program in an unknown state, leading to anything from (at best) buggy behavior to (at worst) permanently corrupting the state of user's important data.

See also Should you catch all exceptions?

But, assuming you're going to do this anyway, you're not going to be able to use the LogUnhandledException() method to set the Handled property in the event args, because each of those events is different. Only the DispatcherUnhandledException event even has a Handled property to set. The UnobservedTaskException has an Observed property which you can set, and the AppDomain.UnhandledException event doesn't even have an analogous property.

However, you can of course specialize each handler to do that. For example:

protected override void OnStartup(StartupEventArgs e)
{
     AppDomain.CurrentDomain.UnhandledException += (s, ex) =>
     LogUnhandledException((Exception)ex.ExceptionObject, 
    "AppDomain.CurrentDomain.UnhandledException");

     DispatcherUnhandledException += (s, ex) =>
     {
         LogUnhandledException(ex.Exception, 
         "Application.Current.DispatcherUnhandledException");
         ex.Handled = true;
     };

     TaskScheduler.UnobservedTaskException += (s, ex) =>
     {
         LogUnhandledException(ex.Exception, 
         "TaskScheduler.UnobservedTaskException");
         ex.SetObserved();
     };
}
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • Thanks for the advice.My original code example is very simplified and handled is only for testing purposes. In your example I get an error on line `ex.SetObserved();` Error CS0200 Property or indexer 'UnobservedTaskExceptionEventArgs.Observed' cannot be assigned to -- it is read only –  Aug 29 '17 at 13:04
  • Sorry I got that error on `ex.Observed = true;` , `ex.SetObserved();` is fine. I didn't spot you had made an edit. Thanks a lot for you help. –  Aug 30 '17 at 11:54