Saturday, December 26, 2009

Robust .NET Exception Handling

After receiving an Amazon Kindle 2 for Christmas the first book I purchased was Lee Dumond's Robust ASP.NET Exception Handling. Coming to .NET from a Java background I had not bothered to look deeply into the exception handling classes available in the base library.

The book moves from the basics of exceptions through to best practices and patterns for handling exceptions in .NET. I picked out the following as generic .NET gems (i.e. not specific to ASP.NET):
  • The GetBaseException method can be used to find the root cause of all exceptions in the exception chain
  • ArgumentException contains a ParamName string that gets the name of the parameter that caused the exception
  • Objects that implement IDisposable can be instantiated in a using statement as an alternative to a finally block
  • Use throw rather than throw ex as this resets the call stack from the point of the throw
In addition some handy conventions to follow in my own implementations:
  • ArgumentNullException and ArgumentOutOfException should be thrown in situations whereby the application cannot provide it's defined functionality
  • InvalidOperationException is useful for wrapping original exceptions
  • Safe Casting - as and is can be used to avoid cast exceptions. as returns null if the cast cannot be performed and is returns true or false whether or not the cast would succeed
  • Safe Parsing - use TryParse rather than Parse for value types to avoid FormatExceptions. TryParse returns true or false and an out parameter. This TryX pattern can be reused for your own implementations
The book also provides a useful pattern for handling exceptions that occur during the execution of an AJAX postback:
<asp:ScriptManager ID=”ScriptManager1” runat=”server”
AllowCustomErrorsRedirect=”false” />
...
<script type=”text/javascript”>
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(OnEndRequest);
function OnEndRequest(sender, args) {
var errorElement = $get(“errorMessage”);
if (args.get_error()) {
errorElement.innerHTML = “An error occurred while attempting to fulfill your request. “ + “Please try again.”;
args.set_errorHandled(true);
}
else {
errorElement.innerHTML = “”;
}
}
</script>
Following on from this the book provides some brilliantly flexible patterns for handling exceptions in ASP.NET. For these you will have to go and get the book. I'm off to implement them into a utility library and a recently published ASP.NET application.

2 comments:

Lee Dumond said...

Really glad you enjoyed the book!

Just a clarification - one of your bullet points states "Custom exceptions should be derived from System.ApplicationException rather than directly from System.Exception".

I certainly hope I didn't leave that impression. ;) Actually, the OPPOSITE is the case -- one should derive custom exception classes directly from System.Exception, not System.ApplicationException.

If you look at the CLR, you'll see that ApplicationException derives from Exception, but adds no utility to it at all. That being the case, ApplicationException does nothing but add a extra layer of inheritance you don't need.

Unfortunately, I didn't really go into too much depth about custom exceptions in the book. Mostly due to space considerations, but also because custom exceptions are a framework thing, and not so much and ASP.NET web development thing.

Anyway, let me know if you have any questions about the material, and thanks for the very kind review.

Gareth Thomas Hill said...

Thanks for the comments Lee.

I've re-read the ApplicationException section and you are correct - I just read it wrong!

Great custom handler by the way - just finished implementing it in an existing web application.