Practical ASP.NET

Handling Runtime Errors Globally

Unhandled runtime errors hit the best of us. But if you catch them at the Page and Application levels, you'll save yourself a lot of grief.

This column isn't for you; your applications don't have runtime errors. But you have a friend who gets errors. And this column is for him.

You should put Try...Catch blocks around any piece of code in your application that might fail. But you if you put all of your code around in Try...Catch blocks, you lose the ability to signal which sections of your code are likely to generate errors. This means that you'll have some sections outside of Try...Catch block that can have "unhandled" errors.

However, even so-called "unhandled" errors are handled because when an error occurs, the exception that's generated bubbles up through the call tree until it arrives at the default ASP.NET error handler. When the errors get to the ASP.NET error handler, your application is terminated, the white and tan error screen all developers are familiar with is displayed, and there's nothing more you can do in your code.

You can prevent exceptions from getting to the default handler -- and stay in control -- by catching "unhandled" errors at the Page and at the Application level.

Page Level Error Handlers
When an unhandled error occurs in a page (or in any code called from the page), the Page's Error event is fired. In that event you'll typically want to figure out what's gone wrong. Your best resource for that is the Server object's GetLastError method; it hands back the Exception object for the last error that occurred in the page:

Protected Sub Page_Error(ByVal sender As Object, _
                         ByVal e As System.EventArgs) Handles Me.Error
Dim ex As Exception
ex = Me.Server.GetLastError()

End Sub

However, just because you've caught the error, that doesn't mean that the error has finished its travels. By default, the error will continue to bubble up the call tree until it reaches the default ASP.NET error handler and terminates your application. To prevent the error from continuing its trip up the tree, you must call the Server object's ClearError method:

Me.Server.ClearErrror

The pattern in the Page Error handler is very simple. Therefore:

  • Try to determine what the error was.
  • Try to determine what you can do about it.
  • If you can deal with the error, clear the error.
  • If you can't deal with the error in the page, do nothing and let the error continue to bubble up the tree.

Application-Level Error Handlers
If you can't deal with the error, you should probably write the error to an error log of some kind (some day you can review that log, figure out what's going wrong and fix it) and direct the user to your own error page. If, regardless of which page has the error, you're always going to write to the same error log and send users to the same error page, then you should do that at the application level, not the page level.

To catch unhandled errors not cleared at the application level, you need to add code to the Application_Error event in your application's Global.asax file. In ASP.NET you don't get a Global.asax file by default so you'll have to add that file (in the Add New Item dialog, it's called the Global Application Class).

As in the Page Error event, you'll want to retrieve the latest exception but you don't need to clear the error (at least in ASP.NET 2.0 and later). Once you have the exception you can write to your error log and, after that, direct the user to your site's error page. A typical routine looks like this:

Sub Application_Error(ByVal sender As Object, ByVal e As  EventArgs)
Dim ex As Exception

ex = Server.GetLastError
ErrorLog.Write(ex)
Response.Redirect("MyError.htm")

End Sub

You, of course, never have unhandled runtime errors in your code. But I'm sure that your "friends" will appreciate it if you share this information with them.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Compare New GitHub Copilot Free Plan for Visual Studio/VS Code to Paid Plans

    The free plan restricts the number of completions, chat requests and access to AI models, being suitable for occasional users and small projects.

  • Diving Deep into .NET MAUI

    Ever since someone figured out that fiddling bits results in source code, developers have sought one codebase for all types of apps on all platforms, with Microsoft's latest attempt to further that effort being .NET MAUI.

  • Copilot AI Boosts Abound in New VS Code v1.96

    Microsoft improved on its new "Copilot Edit" functionality in the latest release of Visual Studio Code, v1.96, its open-source based code editor that has become the most popular in the world according to many surveys.

  • AdaBoost Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the AdaBoost.R2 algorithm for regression problems (where the goal is to predict a single numeric value). The implementation follows the original source research paper closely, so you can use it as a guide for customization for specific scenarios.

  • Versioning and Documenting ASP.NET Core Services

    Building an API with ASP.NET Core is only half the job. If your API is going to live more than one release cycle, you're going to need to version it. If you have other people building clients for it, you're going to need to document it.

Subscribe on YouTube