Reputation:
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?
Upvotes: 9
Views: 2822
Reputation: 70652
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();
};
}
Upvotes: 7