1

This theme from my preveus question: How to remove and create log in Windows Event Viewer

I created wpf app. I'm catching Unhandled exception with 3 ways:

public partial class App : Application
{
    public App()
    {
        DispatcherUnhandledException += App_DispatcherUnhandledException;
        Dispatcher.UnhandledException += Dispatcher_UnhandledException;
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    }

    private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {

    }

    private void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {

    }

    private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {

    }
}

I'm creating exception like this:

   public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        throw new Exception("Test exception");
    }
}

After executing method (Dispatcher_UnhandledException, CurrentDomain_UnhandledException,App_DispatcherUnhandledException) this exception is still throwing. And Windows Event Viewer is creating log like this

Description: The process was terminated due to an unhandled exception. Exception Info: System.InvalidOperationException at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(System.Data.Common.DbConnection, System.Threading.Tasks.TaskCompletionSource1<System.Data.ProviderBase.DbConnectionInternal>, System.Data.Common.DbConnectionOptions, System.Data.ProviderBase.DbConnectionInternal, System.Data.ProviderBase.DbConnectionInternal ByRef) at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory, System.Threading.Tasks.TaskCompletionSource1

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
Dilshod K
  • 2,924
  • 1
  • 13
  • 46
  • Do you mean that none of those 3 methods are actually being called when the exception is thrown? I'm not really sure what you meant when you said "After executing method (...)". – Broots Waymb Dec 10 '18 at 16:04
  • You should probably fix the original exception, or at least log it, instead of trying to hide it. A failed database connection won't fix itself. – Panagiotis Kanavos Dec 10 '18 at 16:15
  • Set the handled to true ofvthe eventargs to stop event propagation. – Cleptus Dec 10 '18 at 16:51

2 Answers2

6

In your handler method, you need to tell .NET that you handled the exception. Otherwise it will still kill the application. You do this by using the Handled property of the DispatcherUnhandledExceptionEventArgs object.

So if you decide that you want to continue the application despite the exception, set it to true:

private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
    e.Handled = true; //let's continue and see if anything explodes
}

That said, you should still handle exceptions where they could occur (as much as possible). Take the example you gave, which looks like a network connection problem. If you caught that exception where you create the connection, you can tell the user something more specific like "I could not connect to the database. Is your network working?" Whereas if you rely on this to catch that kind of error, you can only regurgitate the exception message, which will often not make sense to the user.

This should be used as a last-resort fail-safe. It should not replace catching exceptions throughout your code.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • Try catch should be rare in your code rather than "throughout" it. Unless you are doing something unusual. https://stackoverflow.com/questions/14973642/how-using-try-catch-for-exception-handling-is-best-practice – Andy Dec 10 '18 at 16:36
  • 1
    @Andy That depends how you define "rare". When you are calling methods in code you do not control (especially when I/O requests are involved) then you can't control if exceptions will be thrown. Connecting to a database is a perfect example: If you catch an exception *when the attempt is made*, then you know it is safe to give up or maybe retry. But if you leave that exception to be caught by the `UnhandledException` event, then it doesn't know the difference between a failed network connection and an out of memory exception. – Gabriel Luci Dec 10 '18 at 16:47
  • Please follow the link I posted. – Andy Dec 10 '18 at 16:55
  • 1
    @Andy I did, and it supports what I said. The accepted answer there says "I enclose in 'try/catch': All the operations that I know might not work all the time (IO operations, calculations with a potential zero division...)" – Gabriel Luci Dec 10 '18 at 16:57
  • 1
    What it comes down to is this: As a user, would you like to see an error message that says, "The database could not be reached. Do you want to retry?" or "The process was terminated due to an unhandled exception." – Gabriel Luci Dec 10 '18 at 16:59
-2

Global error handling like this should close the app down. You have an exception from somewhere-or-other and the app is in some unknown state.

If you eat the error and just let the user carry on then you have no way of knowing what will happen.

The "standard" approach is to log the error then shut down with

 Application.Current.Shutdown();
Andy
  • 11,864
  • 2
  • 17
  • 20