I think this is the worst advice on exception handling I have ever read, sorry Joel.
I know this is an old post, I know Joel is entitled to his own opinion and I know he has the right to write his code as he sees fit. But as an opinion leader he influences others. While many times I enjoyed his fun and well written articles on the business of software, this time I was pretty disappointed.
Basically he recommends returning error codes from methods instead of throwing exceptions. His justification for this advice is a parallel he draws between exception throwing and GOTO statements and he points to Edsger W. Dijkstra’s “Go To Statement Considered Harmful” paper.
But here is what Dijkstra actually wrote about this issue:
“The go to statement as it stands is just too primitive, it is too much an invitation to make a mess of one’s program. One can regard and appreciate the clauses considered as bridling its use. I do not claim that the clauses mentioned are exhaustive in the sense that they will satisfy all needs; but whatever clauses are suggested (e.g. abortion clauses) they should satisfy the requirement that a programmer independent coordinate system can be maintained to describe the process in a helpful and manageable way.”
The “abortion clauses” are “exception handlers” and while they are indeed hidden GOTOs they are acceptable as they are implemented in a very structured way in languages like Java, C#, C++ and many others. On the other hand all constructs in structured languages are implemented with hidden GOTOs underneath.
The big advantage brought by exception handling concepts in modern languages is the clear separation of the failure paths. Now programmers have a very specific and structured mechanism for error handling.
Joel thinks exceptions are worse than GOTOs because:
- They are invisible in the source code
- They create too many possible exit points
I fail to see how these problems are specific to exceptions and how they don’t apply to the proposed solution of returning error codes.
When I look at a piece of code I will know if various method/function calls return error codes only if I am a psychic. Without good documentation you are as helpless as with exception handling. I still remember inspections of piles of C/C++ code, written by naive programmers, where function calls were made with no checking of the returned error codes or the global variables used to keep transient error codes.
On the other hand in Java you still stand a chance if the methods/functions you call throw checked exceptions since the compiler will tell you about them (I know some programmers think checked exceptions are evil but that is another discussion).
The problem of too many exit points, while valid, is not a problem caused by exceptions. It is more a problem of programming style and very related to an understanding of the KISS principle. Even without exceptions one can have multiple return statements in a function. And with the “returning of error codes solution” you will likely get this kind of code from less experienced programmers.
Paraphrasing what Joel writes I could say: “Every time you call a function that can return an error code and you don’t check it on the spot, you create opportunities for surprise bugs caused by functions that terminated abruptly, leaving data in an inconsistent state, or other code paths that you didn’t think about.”
One thing to realize is that no mater what solution you choose to deal with errors, this doesn’t change the nature of your problem: you still have to deal with them in the right context. And this is the big challenge, dealing with exceptions (or error codes) in the right context.
The “better alternative” recommended by Joel (return error codes) is full of problems (as he already admits in the article):
- The domain results returned by the fucntion usually don’t leave any space for error codes
- Avoiding the above problem means using “out” parameters (think about preparing the function call by allocating memory for the results and other pleasant activities).
- Handling the errors means mixing the success path and the error paths in a very convoluted way
- The code becomes ugly and complicated and the logic of the success path is hidden by all error code checking
All these problems seem, to Joel, more acceptable than structured exception handling. They don’t seem to me.
PS: If Joel changed his opinion in the 5 years since he wrote that post he should at least go back and put a warning there for his readers.
By the way, you can read a commented version of Dijkstra’s paper here.
This post is part of a series on exceptions:
- Thoughts on Java exceptions
- Some exceptions are more equal than others
- Less than perfect exceptions hierarchy
- Checked exceptions are priceless… For everything else there is the RuntimeException
- Design the failure case – Part 1
- Design the failure case – Part 2
- Exception design relativity
- Bad advice on exceptions from Joel