It’s been a while since I wrote the last article I know, but I’ve been busy creating new applications and maintaining the old ones and hey we are moving across the whole world to New Zealand. So, you can turn a blind eye on me and I promise I will write many interesting articles. Deal?
Let’s get back to the business. The question of today is about throwing exceptions in your program. In my career, I saw plenty of code bases where exceptions were brutally overused. I call this phenomenon an exception driven programming and I don’t like it.
The main problem is that the code where exceptions are used to create a program flow is hard to maintain and its purpose is not clear on the first look.
Usually, the code is wrapped in one almighty catch all exceptions block which is not a correct behavior and it can swallow unintended runtime exceptions, such as OutOfMemoryException, StackOverflowException, etc.
Also, when you throw an exception you pay a massive performance cost, so it’s not wise to do so when you don’t need it.
So, how you should work with exceptions?
First of all, use exceptions only for exceptional situation. The two words have the same root for some reason. Never use exceptions for driving your program logic.
Always try to use existing classes and .NET contains lots of them. Before you create yet another new MyException™ class always do a research if it’s really necessary and most of the time you’ll be fine with existing types. Using existing types brings clarity and understanding to your code base and your colleagues or your future self will like you (or at least won’t hate you as much).
Whenever you work with exceptions, throw the most specific type and catch the most specific type as well. You are adding more information to your code base and more value. Imagine you throw an ArgumentException, is that argument missing? Is it invalid? Is it of another type? ArgumentOutOfRangeException could answer these questions.
Let’s get back to the first point of when you should use exceptions and how often. Andrew Hunt in Pragmatic Programmer says:
Assume that an uncaught exception will terminate your program and ask yourself, “Will this code still run if I remove all the exception handlers?” If the answer is “no”, then maybe exceptions are being used in nonexceptional circumstanes.
A brilliant question you should ask yourself every time you create a new program flow, so ask it often!
To sum it up:
- be specific and use the most concrete types,
- don’t create your own exceptions and
- use exceptions exceptionally.
Break any of these rules and you’ll have to deal with exception gods or your angry colleagues – and maybe it’s easier to deal with the first ones.