What!? A .NET Application Can Die?
WinForms application exception handling has a twist on it. Exceptions for the main thread and the main thread only, go to a different handler. You'll need to add a delegate to the Application.ThreadException member which has the type System.Threading.ThreadExceptionEventHandler in order to handle them. If you want notification of exceptions from other threads, you'll have to also set the AppDomain.CurrentDomain.UnhandledException event as I discussed in the previous section.
Another interesting little problem is that unless you set both exception handlers before calling Application.Run, you won't be able to debug them. Consequently, you'll want to ensure you set them.
While helpful, especially when you click on the Details button to see what happened it does not make debugging any easier. What would be nicer is if you could get the Just In Time debugger to pop up instead so you could debug the problem. Fortunately Microsoft thought that might be useful. In the application configuration file, add a system.windows.forms element under the configuration element and set the jitDebugging attribute to true and now you'll get the JIT dialog instead of the normal exception.
<configuration> <system.windows.forms jitDebugging="true" /> </configuration>
Where WinForms applications are slightly different than console applications, handling exceptions in ASP.NET applications is radically different. If you want notification of errors on the page, the System.Web.UI.Page.Error event gives you the errors that occur in that class. In handling System.Web.UI.Page.Error, you'll also want to look at the Page.ErrorPage property as that String contains the page the user wants to show if there is an unhandled exception.
For handling exceptions globally to the application, the System.Web.HttpApplication class, which is the base class for Global in your GLOBAL.ASAX file, has the System.Web.HttpApplication.Error event. The System.Web.HttpApplication.Error event is only called if you do not handle the error on the page or if you re-throw the exception from your System.Web.UI.Page.Error handler.
Inside your System.Web.HttpApplication.Error handler, you can access the System.Web.HttpApplication.Server property as it contains the System.Web.HttpApplication.HttpServerUtility class which will retrieve the error through its GetLastError method. Additionally, if you'd like to keep the application running, instead of terminating, you can clear the last error with the appropriately named ClearLastError method.
While .NET does make your applications much better by avoiding the memory issues and crashes we've seen in the past, you can still have numerous unhandled exceptions. However, instead of having one place to handle them all, like we did with Win32, there's a little bit of difference in .NET. While ASP.NET has its own way, WinForms and Console applications are similar. However, with the fact that unhandled exceptions terminate the main thread but not any other threads, means you'll have to pay attention to ensure your application runs as you would expect. I hope this column straightened out everything for you on handling your exceptions!
Download: DeadDotNet.zip - 8 kb.
About the Author
John Robbins is the co-founder of Wintellect ( http://www.wintellect.com), a consulting, debugging, and education firm that helps client's ship better code faster. He is also the author of Debugging Microsoft .NET and Windows Applications (Microsoft Press) as well as the Bugslayer columnist for MSDN Magazine. Before founding Wintellect, John was an architect and product manager at NuMega Technologies for products such as BoundsChecker, TrueTime, and TrueCoverage. Prior to joining the software world, John was a Paratrooper and maroon Beret in the U. S. Army.
# # #
Page 2 of 2