Code Focused

It's Safe to Handle Unhandled Visual Basic and C# Exceptions

Pile on the exceptions, and .NET will have your back with the tools it provides at your disposal.

Unhandled exceptions are a bit of a misnomer. In .NET, every exception is handled. By the time you access the specifics of an error in your Try-Catch block, the Framework has already analyzed the problem, built a structure to contain its details, examined the stack trace, and used reflection to pinpoint the location of the error, among other mundane tasks. In short, when errors occur, .NET serves them up to your code in a neatly packaged, highly examinable data block.

As busy as .NET is in dealing with exceptions, it is still a gentleman. Even if you choose to ignore thrown events when they occur, the Framework gives you one more chance, through the medium of unhandled exception processing.

Visual Basic makes it especially easy to intercept and process these nearly lost exceptions through its Windows Application Framework. When supported by a specific project type, the framework enables a handful of programmer-friendly events, including an UnhandledException event that's precisely what you're looking for. To access the event, open the Application tab of the Project Properties panel in your project, ensure that the Enable Application Framework checkbox is selected and, finally, click on the View Application Events button.

This button click adds the ApplicationEvents.vb file to your project. Using the event dropdown controls along the top of the code editor, access the UnhandledException event. The file now contains this exciting code:

Imports Microsoft.VisualBasic.ApplicationServices
Namespace My
  Partial Friend Class MyApplication
    Private Sub MyApplication_UnhandledException(
      sender As Object, e As UnhandledExceptionEventArgs) _
      Handles Me.UnhandledException

    End Sub
  End Class
End Namespace

After you add this handler to your project, any exception not fully processed within a Catch block arrives here, ready for last-second analysis. The e.Exception parameter field presents the full details on the exception in question. That's nice and all, but if you still choose to do nothing in this method, your program will crash. That's because the default behavior after moving through the UnhandledException handler is to exit the program. If you want your user to continue working without complaint, set the ExitApplication flag to False within the handler:

e.ExitApplication = False

C# lacks the application framework, so unhandled exception processing is configured when your program first begins, as part of the Main method. There are a few variations to the setup, depending on whether you want a Windows Forms or non-Windows Forms focus. But as with Visual Basic, all of the options use an event handler to capture and process the previously unhandled error. (These variations can be used in Visual Basic, as well, by accessing the same classes and events utilized in C#.)

In Windows Forms applications, your code should monitor the UI-thread-specific Application.ThreadException event. First, add the handler to the class that contains your Main method, or to some other convenient and accessible part of the code:

// Assumes: using System.Threading;
private static void UIGlobalErrorHandler(
  object sender, ThreadExceptionEventArgs e)
{
  // ----- e.Exception exposes the error object.
}

Then back in your Main method, add code to link up the event to the handler:

// Assumes: using System.Threading;
Application.ThreadException +=
  new ThreadExceptionEventHandler(UIGlobalErrorHandler);
Application.SetUnhandledExceptionMode(
  UnhandledExceptionMode.CatchException);

For project types other than Windows Forms -- or to deal with certain types of non-UI exceptions within Windows Forms applications -- your handler attaches to an event at the application-domain level. The event handler looks a lot like the UI version, but with a different data type for the passed-in exception container:

private static void GlobalErrorHandler(
  object sender, UnhandledExceptionEventArgs args) 
{
  // ----- e.ExceptionObject exposes the error object.
}

Activate the event using a normal event-connection syntax in your Main method:

AppDomain.CurrentDomain.UnhandledException +=
  new UnhandledExceptionEventHandler(GlobalErrorHandler);

Unlike the Visual Basic version, these unhandled exception handlers do not terminate easily. Normally, the program will continue to run even after error processing. To exit the program abruptly, you need to call one of the framework termination methods, such as Application.Exit.

As a programmer, the choice to deal with errors or let them pile up on the user's screen is entirely up to you. But with the .NET Framework giving you so many tools to manage errors when and after they occur, it's practically begging you to live up to your exception-processing expectations.

About the Author

Tim Patrick has spent more than thirty years as a software architect and developer. His two most recent books on .NET development -- Start-to-Finish Visual C# 2015, and Start-to-Finish Visual Basic 2015 -- are available from http://owanipress.com. He blogs regularly at http://wellreadman.com.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events