Why failing gracefully matters
Posted in .NET Development,Web Development by Ray Schauer on January 14th, 2009
Unfortunately, the user is sometimes the last thing on a developer’s mind. Equally unfortunately, the user should be the first thing on any developer’s mind. Code style, speedy delivery, and efficient architecture are all for naught when the first error is discovered.
What happened? What caused the error? Is the user to blame? Or, is it a legitimate bug? In most cases, the error displayed will end up being a stack trace. While this may be handy to a developer, it is useless and overwhelming to your average user.
I’ve heard several “reasons” over the years. Do any of these sound familiar?
- Its helpful to see the errors during development.
- I’ll toss a generic catch all error handler in when I’m done.
- We should never see this state anyway.
I’ll admit, I’ve used one (or more) of these excuses myself when rushed before. In the end, it only came back to haunt me. Why? Contrary to popular belief, the stack trace isn’t all that useful. It simply tells you what happened at the point of the error, not what led up to the error. When diagnosing errors in an application not designed to fail gracefully, developers often find ourselves attempting to recreate an error with little information on what led up to the error.
Step 1: Fail Gracefully (keep the user in mind)
So, how can we help ourselves? We start by helping the user. Remember this. Never, under any circumstances, ever, display an unfriendly error message to the screen. This is a catastrophic failure. Should something go wrong, the user should be assured that the appropriate parties have already been notified, that someone is looking into the issue. A branded 404 or 500 page should be utilized at all times. Including development. This ensures it will not be overlooked during deployment or QA. This also forces us to implement steps 2-3.
Step 2: Structured Exception Handling
If we can’t see the stack trace through the screen output, how can we see it? Well, to be blunt, a stack trace is the result of an un-handled error. This means we missed something. .NET allows us to use structured exception handling. By this, I mean try, catch, finally, and throw.
try
{
// Code expected to raise an exception.
}
catch(Exception e)
{
// Code to handle an error.
}
finally
{
// Any final cleanup.
}
Ok, so now we’ve managed to provide logic allowing us to capture errors as they are generated. Now what? If possible, we utilize the catch block to correct inputs or reset our current state to a non-error state. However, this isn’t always possible. In these cases, we can utilize the throw mentioned above to generate our own custom errors which can be more informative (relate to the current business logic).
Finally (like the pun?), we can perform any clean up required to restore the application to a usable state.
Step 3: Logging Matters!
Wait one second! Before we throw the error, we need to log what we have attempted to do. Why? Doing this will allow us to avoid having to trace back through the application guessing at what the inputs to the various functions may have been.
Apache’s log4net is a library designed to simplify and streamline the logging process. log4net is a port of the excellent log4j Java library. It claims to be as fast and flexible as log4j. Logging libraries often allow developers to insert logging at several levels. The most common logging levels configured are:
- TRACE
- DEBUG
- INFO
- WARN
- ERROR
- FATAL
Production environments would typically be configured at ERROR or FATAL while development environments would be configured at TRACE, DEBUG, or INFO. Staging environments typically run at INFO or WARN. We are currently in the process of putting log4net through its paces (does it compare to log4j?). More on that later. The lesson here is LOG!
So Why Does Failing Gracefully Matter?
As you can see, failing gracefully isn’t an afterthought. It’s not something that can be tagged on to your application at the end. However, by following these three steps, you can increase the supportability and maintainability of your application. And, if you are like me, you will find yourself catching more bugs ahead of time as you keep an eye on the log files generated.

