Handling unhandled exceptions
Exception handling is a vital part of software development. When an exception occurs at runtime, due to any error in the code, we handle those with a try {} catch {}
block. The try {}
block contains the code where the exception occurred; the catch {}
block knows how to handle that, based on the type of the exception. After the exception has been handled, the normal execution of the program continues without affecting the application.
Though, in most of the cases we handle, there could be cases that may go unnoticed and come into the picture at runtime. Such an unhandled exception crashes the application. In this recipe, we will learn how to catch the unhandled exceptions in the WPF application and close the application properly.
Getting ready
To get started, open the Visual Studio IDE. Now create a new project, based on the WPF Application template, and call it CH01.UnhandledExceptionDemo
.
How to do it...
Let's start the demonstration by following these steps:
- Open the
MainWindow.xaml
page, and add two radio buttons and one button on it. The first radio button will cause an exception handled in atry {} catch {}
block, whereas the second radio button will throw an exception that will go unhandled. Add the following code into yourMainWindow.xaml
:
<Window x:Class="CH01.UnhandledExceptionDemo.MainWindow" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="UnhandledException Demo" Height="120" Width="400"> <Grid Margin="10"> <StackPanel Orientation="Vertical"> <RadioButton x:Name="radioOne" GroupName="type" Content="Handle in Try/Catch Block" IsChecked="True" Margin="4"/> <RadioButton x:Name="radioTwo" GroupName="type" Content="Handle in Unhandled Block" IsChecked="False" Margin="4"/> </StackPanel> <Button Content="Throw Exception" Width="120" Height="30" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10" Click="OnThrowExceptionClicked"/> </Grid> </Window>
- Open the
MainWindow.xaml.cs
file to add the button-click event handler. Add the following code block inside the class:
private void OnThrowExceptionClicked(object sender, RoutedEventArgs e) { if (radioOne.IsChecked == true) { try { throw new Exception("Demo Exception"); } catch (Exception ex) { MessageBox.Show("'" + ex.Message + "' handled in Try/Catch block"); } } else { throw new Exception("Demo Exception"); } }
- Go to the
App.xaml.cs
file and override theOnStartup
method to have the application levelDispatcherUnhandledException
event registered as shown in the following code:
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); DispatcherUnhandledException += OnUnhandledException; }
- Add the
DispatcherUnhandledException
event handler into theApp.xaml.cs
and handle the exception as shown in the following code, but with an empty code block:
private void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { }
- Let's build and run the application. You will see the following UI on the screen:
- It will have two radio selectors and one button in the application window. When the first radio button is checked and you click on the
Throw Exception
button, it will generate an exception in atry {}
block, which will then immediately be handled by the associatedcatch {}
block without crashing the application. The following message box will be shown on the UI:

- For the second radio button, when checked, if you click on the
Throw Exception
button, the exception will go unhandled and will be caught in theApp.xaml.cs
file, under theOnUnhandledException
event, and the application will crash:

- Open the
App.xaml.cs
once again and modify theOnUnhandledException
event implementation, as follows, to handle the thrown exception:
private void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { e.Handled = true; }
- Now run the application once again, check the second radio button and click on the button. You will notice that the application will not crash this time.
- Click the
Throw Exception
button multiple times. The application will continue as-is, without causing any crash of the UI.
How it works...
When you handle this kind of uncaught/unhandled exception by specifying e.Handled = true
, your application will not crash and will continue running. The best part of catching an unhandled exception is logging the unknown/unhandled errors, so that you can investigate the root cause behind these exceptions and fix them in future builds.
When there's a critical error, you can restart the application programmatically from this block.
There's more...
You can also use the AppDomain.CurrentDomain.UnhandledException
event handler to catch any unhandled exceptions, but you won't be able to handle it in a way to continue running the application. When used, you can log the error and terminate/restart the application.
Note
Unhandled exceptions handled in the DispatcherUnhandledException
event, by specifying e.Handled = true
will not route to the AppDomain.CurrentDomain.UnhandledException
.