The Right Approach to Exceptions

Jonathan M Davis jmdavisProg at gmx.com
Sat Feb 18 18:21:46 PST 2012


On Saturday, February 18, 2012 19:59:52 Robert Jacques wrote:
> But you _always_ know what went wrong:

No you don't. Take getopt for instance. If I want to appropriately handle what 
went wrong that caused getopt to throw an exception, I need information on 
what went wrong. I need to know what flag failed and why it failed (e.g. 
unknown or it was given an invalid value). Exception doesn't give you any of 
that. You need a more specific exception type to get that information.

> An unexpected error occurred while
> trying to do X, where X is whatever is inside the try-catch block.
> Exceptions are for exceptional situations and not supposed to be used as a
> form of out of band information return (or at least that's what every
> programming book tells me).

Exceptions are for handling when something goes wrong in your program - 
frequently from interacting with users or I/O. It's much cleaner to write code 
which assumes that opening a file and reading for it will work than to check 
every operation to see whether it succeeded or not. Then you can just set up a 
try-catch block around it, and handle the error if it occurs. Whether the 
exception is "unexpected" is debatable. It _is_ expected in the sense that if 
something goes wrong with opening and reading the file, you're going to get an 
exception, and that's not a bug in your program, but it's not expected to 
happen in the common case. It's still expected to happen at least some of the 
time though. It's not like "something went wrong and we don't know what to 
do." If that's the case, you're moving towards Error territory, though that 
depends on if you can recover from a failed operation even if you have no clue 
what went wrong.

When you avoid using exceptions is when there's a high chance that the 
operation will fail. Then you have the function return whether it succeeded or 
not, and exceptions would just slow the program down (I believe that a number 
of socket operations fall in this category for instance). But if the normal 
case is that it will work but occasionally it won't, an exception is the 
better way to go, since it leads to cleaner code.

What's truly horrible is when you throw exceptions for normal situations (an 
extreme example being that you throw when an operation succeeds).  _That_ is 
completely misusing exceptions, but most people don't do that. Exceptions are 
for error handling. If anything, I think that talk about "exceptional" cases 
leads people to completely misuse exceptions, because they often end up using 
them only for cases where Error should be used - that is unrecoverable 
situations.

Personally, I'm against the use of error codes and returning whether an 
operation succeeded instead of using exceptions in the general case and that 
those should only be used when failure is _likely_. As long as it's at all 
reasonable to assume that an operation will succeed, using an exception to 
handle when it doesn't is far better than using the return value to indicate 
failure.

- Jonathan M Davis


More information about the Digitalmars-d mailing list