The two golden rules of exception handling
Posted at 22:39 on 23 April 2008
The standard instruction that tends to get bandied about on when to throw exceptions is probably the most useless piece of non-advice that I have ever come across.
"You should only throw exceptions in conditions that are exceptional."
What on earth is that supposed to mean? It's like saying "You should only eat food that is edible." And that doesn't tell you, for instance, that Agaricus bisporus is edible but Amanita phalloides isn't.
However, there are actually two very simple guidelines that tell you, in terms that are much easier to understand, exactly when to throw an exception and when to catch one. They are:
1. Throw an exception when your method can't do what its name says it does.
Scott Hanselman blogged about this a while ago and it is probably the best piece of advice I've read on the subject:
If your method is called "Save" and it can't Save, then throw. If it's called DoSomething and it can't DoSomething, throw. The idea is that the method name is a verb and a contract. It's promising to do its best and if it can't do it, it's very likely exceptional.
It's clear, unambiguous, to the point and easy to understand. Each method should do one thing, its name should say what that one thing is, and if it can't do that one thing, that is when you throw an exception.
2. Don't catch an exception unless you intend to do something about it.
Now the first rule is about throwing exceptions; it doesn't say anything about catching them. However, Patrick Cauldwell, whom he links to, has this to say:
Never catch Exception
- If it's not a problem you know about, delegate up the call stack, because you don't know what to do about it anyway
Far too often I see code that catches and silently discards all exceptions. This may give your program a superficial appearance of being more robust, but in actual fact, it is merely masking over a problem that may need to be addressed and dealt with.
Remember that an exception means that something has gone wrong. Unless you know exactly what to do about it to recover from the situation, you should let it propagate up to the top level of your program, where you should log it, and, if appropriate, fire off an e-mail to the developers and/or systems administrator to let them know about it.
There may be times when you need to catch Exception. Transactions may need to be rolled back, resources may need to be disposed, and so on. However, unless you can recover from the situation that caused the exception in the first place, you should re-throw it. And even if you do swallow exceptions for any reason (and you shouldn't do so unless you have a good reason), you should never do so silently: the very least you should do is record a warning in the application's event log.