An interesting viewpoint on a downside of exceptions here. I originally got to it from here (has a section on exceptions at the bottom).
I don’t entirely agree, however. I like exceptions, they encourage you to think about your program from the what-can-go-wrong viewpoint. One normally writes software with the goal in mind, and thus takes an optimistic view of what could go wrong. Error codes are too easy for me to forget.
What I believe is really at stake here is the difference in mental models between exceptions and the usual coding model.
Normally your function has a well defined input and output, makes certain assumptions about its context, and the order in which it executes each step is well defined. In the usual coding model, you’re focusing on each step that takes you closer to your goal. Error codes don’t interfere with that model.
In the exception model, you have to stop and think about what could go wrong. This leads you down all sorts of tangents. If your code has to handle a checked exception, it’s irritating: you haven’t reached the goal yet, and you have to worry about what could go wrong? And it’d be more than a little distracting to have to pause every time you type a statement and consider: is there an assumption here that I should notify my caller about if it’s not true?
Another factor that reduces the effectivness of checked exceptions is that the developer usually decides that the appropriate action is to just log the problem, or not handle it all and pass the problem to someone else. And from his or her immediate view, that’s absolutely correct: the programmer is programming, he/she will see problems on the screen, fix it, and carry on. So handling exceptions often seems a pointless distraction.
As the linked article at the top says, it’s not that exceptions are bad per se. IMO, the problem is that the model of normal programming (linear, optimistic) conflicts with the model of exception-handling (non-linear, pessimistic). And as the article shows in the case of unchecked exceptions, it’s harder to go back through the code and see that something that should have been handled wasn’t. At least with error codes, you can see from the function signature that something is being returned that’s not being checked.
Personally, I prefer the enforced in-your-face rigor. I can totally see, however, how the error code model would be preferrable and work fine. As is frequently the case, if you’re a good programmer, you’re a good programmer. If you can’t get the model for the constructs and tools to align with your thinking (or vice-versa), then using them will do you no good at all.