Do NOT Catch That Exception!

Ohhh, I’ve recently seen one to many applications where developers try to be safe by catching exceptions all over the place. It can be everything from a small simple method that doesn’t throw that many exceptions to a large method with multiple try/catch statements. Most of those catch blocks just log the exception and rethrow it.

Please do not catch that exception. Let it travel down the call stack. I promise you that you won’t regret it. You’ll get a warm and fuzzy feeling next time you’ll test your application. I promise you! Really!

Why? You’ll get a complete exception with all the details you need to fix the error. The problem with all of those try/catch blocks is they don’t help your application in any way. They just clutter up the code and your log files.

If you still want to catch exceptions: I’ll try to explain the way to do it.

Catching Exceptions in the Correct Way

Yeah. Proper exception handling can be something wonderful. You’ll smile every time you get an exception. First of all: Exceptions only happen when something exceptional occurs. Please have that in mind, because it helps you remember that you don’t need those try/catch block everywhere. That brings us to the golden rule about when to catch exceptions:

Only Catch Exceptions that You Can Handle to Rescue the Situation

You should only catch exceptions if you can deliver the result as promised by the method contract. For instance, if the return value from a method is an User object, you should only catch an exception if you in fact can return a User.

Anything else is not really exception handling but just diagnostics.

There are of course exceptions, namely two of them:

Do Not Let Layer Specific Exceptions Propagate Up the Call Stack

For instance, if the data layer fails and throws a SqlException (if you are using SQL Server), you should catch it and wrap it inside a more generic exception. For instance: Create a DataSourceException which could be used even if you switch data source from a database to a Web Service. You should of course add details to the exception such as the method in your data layer that failed (let’s say “SearchUsers”) and the arguments for that method. Do NOT forget to add the original exception as inner exception.

Update 2013-03-01: I'm not following this rule any more. The only time I wrap exceptions is if I add more context information to help me prevent the exception in the future. It doesn't really matter if the data layer exception is passed up the call stack, since it won't be handled, but just logged in the top layer.

Try/Catch All is OK in the Layer Closest to the User

Ok, so you have let the exceptions propagate through all your layers to the presentation layer (winforms/ASP.NET, etc.). Fine. Go ahead, give the user some fancy error pages. Also log those errors. But just don’t log them. Notify a support team. Send an email to the project lead.

When Everything Else Fails

Are you not sure that your new exception policy will catch all of those exceptions? Is it scary? Then I got the solution for YOU!

ASP.NET: Implement Aplication_OnError(object source, EventArgs e) in your global.asa. It will be called for all unhandled exceptions.

Winforms: Subscribe on Application.ThreadException

Winservices/console apps: Subscribe on AppDomain.CurrentDomain.UnhandledException. The problem with this event is that it will still terminate the application. But there’s a way around that too

WCF: Implement IErrorHandler and log the exceptions in it (added 2013-03-01)

And yes, I've had people argue with me on that when I said "variable assignment and simple math can't throw exceptions" and they've said "what about Out of Memory" and I said "then you got bigger problems you need to catch at a higher level" but I don't know, maybe they have a point?

But they also get a lot of other angry customers (not that I care, I just want my money).

From a serious point of view they violate the contract of every method that they have empty catch blocks in. They can never guarantee that the method returns what is promised by catching arbitary exceptions. Hence they violate rule #1: Only catch exceptions that you can handle.

One implication of empty catch blocks is that the calling code will never be aware of that something failed. Imagine the number hours that have to be spent on trying to figure out why some part of the application fail. The failure can be in an entire different part of the system (some levels up in the call stack) since all calls think that everything went ok.

Exceptions should never been taken lightly, they are after all the last resort that developers take when they can't handle the situation. So if the method that you call can't handle the situation, how can you? (You can, but only in the next version of your application where you've added code to prevent the exception)

Oh it wasn't the empty catch block I was complaining about. It's the exception handling block around something that can't throw exceptions. I encountered this the other day with a method - the method tries to get a value into an output variable, and if not, the function returns false - the function catches all exceptions and returns false status or it succeeds and returns true - no exceptions can be thrown from the method. Still, in the calling code, they wrapped it in a try. AND - they didn't check the return status. So, they failed to understand how the method works, expecting it to throw exceptions for failures, when it's a boolean status-return type method.

Absolutely don't catch it ..if there is an exception then someone should be fixing it and not wrapping it up and stashing it away. If one does need to catch, then the exception should at least be forwarded to a easily accessible log of some type ..with preference one that is queryable or that sends out notifications.

Personally i switched to using healthmonitoring extensively a few years back ..docs are a pain, but once correctly configured it rocks. Even more since i have a custom web based backoffice slapped on top of it, and even propagate jquery, ajax, and window.onerror events back to the server via ajax methods

Some links and code if you are interested:
https://github.com/itechnology/HealthMonitoring.NET

I would like to add to this article that Exception handling is not static, in the ways that there are no de facto solution on how it should be used. Exception handling follows the project or software. Some cases you want the exception to bubble to presentation layer, other time you need to catch the exception and do some business logic before either rethrowing it (never use rethrow, just throw;) or returning an empty data transfer object (DTO).

I kinda feel the DAL (Data Access Layer), should always handle all exceptions related to Acess and Data, and never bubble the exception of that type up to presentation. Reason behind that is the whole SOC (Seperation of Concern) pattern. Each Layer in the code should know how to handle their own exceptions, so the business logic remain within the domain.

Finally, someone to stress on the most crucial topics of all. I agree completely. The only reason of my vote 4 is the omission of the following logical addition:
you need to remove all those try-catches from the actual code with the exception of places where you work with system resources (e.g. File, Tcp Connection, etc.)
in all of these places try-catch should be replaced by try-finally
and of course ensure that resources are freed to the OS in the finally {} block!

how come? you can use either. However still try-finally is more general, since it doesn't bind the lifetime of a resource to the scope of the using statement. for instance you might not want to open a tcp connection every time, but rather keep one and use it over the lifetime of your app.

in fact, my bad, the use case I had in mind is not for try-finally, but try-catch. when you rely on using statement or try-finally, you always close/dispose the resource (regardless of whether an exception is thrown or not), that might not necessary what you want. anyway both try-finally and using are the same!

So I contradicted myself ,but always look at the context and don't follow blindly patterns!

No, no they are not. Using calls the Dispose method at the end of the block. Finally can do anything you want. If, for example, you need to "Close" something, you should use a finally block, unless you know for sure that the Dispose method of the object also "Closes" it. In the case of SQLConnections and some other framework objects, that is the case, and the using block will work correctly, but in libraries and your own code that may not be the case, and using will Dispose the object without calling any other clean-up methods, if that's the way you or the library writers did it.

Most of the time your statement is correct, but knowing the difference between using and try-finally-dispose is important.

yes. you are right. thank you for pointing out, the one big nonsense of C#. that you don't have unified memory management model. in fact you have none whatsoever. you can only if an object expose dispose you need to call it. in cpp it is all in constructor-destructor.

anyway, I ment same as use semantic and that you can either use the onne or the other, but not try-catch!! either useing or try-finally! when working with resources

I think computer viruses should count as life. I think it says something about human nature that the only form of life we have created so far is purely destructive. We've created life in our own image.
Stephen Hawking

A great article and totally agree with you but during development, I do like keeping try-catch in most of the places for easy debug during run time. When release, I clean them up and leave try-catch at presentation layer.

In vb.net, it's possible to capture information about exceptions without catching them. This can be very useful if cleanup code might throw an exception, and one would want to propagate both the cleanup-failed exception and any exception which was thrown prior to cleanup.

Nice feature, but is it really useful? It makes the exception handling a whole lot complex and reminds me of exception frameworks. For instance, the exception handling block in Enteprise Library tells you two things:

a) that you should define polices for when exceptions should be thrown
b) To be able to use those policies you need to have try/catch blocks all over the place.

It brings us far from the easiest exception handling in the world: Only catch exceptions that you can handle.

And quite frankly: Do you really need to have a method (when XXXX) or a policy to determine that for you?

First off, good article, I give it a five. One of my pet peeves (as I see is one of yours too) is when a developer wraps code in a Try/Catch statement without anything in the Catch instead of allowing code to fail then learn how to prevent the exception.

Suggestion, you might consider discussing benefits of overriding the default unhandled exception handler. For example writing code for Winform apps under My.Namespace event UnhandledException or using a user class that inherits from System.ApplicationException. Also might be worth a high level discussion on a) writing exceptions to a log (database, physical file etc.). I have been doing this from Nantucket Clipper to Borland Delphi thru .NET and has been an invaluable method to track down exceptions when users decide not to report an issue.

Yes. I totally agree with you. Exceptions should be documented. It's especially important for libraries. Resharper had a plugin called Exceptional. It could find all exceptions thrown from a method (even from all calls that that method made), but it's long dead

Well. It is generally also bad idea to introduce new types in the system. As the author suggested, keep those on a module level and wrap the original exception inside.
Frankly, I never had the need to use extra type Exception rather than the built-in CLR. ArumentNullException, InvalidArgException and my favorite IllegalOperationException