API Design Myth: Exceptions are for "Exceptional Errors"


I was updating FDG section on exceptions. I added one anntation that I thought I would post here as well:


 








KRZYSZTOF CWALINA


One of the biggest misconceptions about exceptions is that they are for “exceptional conditions.” The reality is that they are for communicating error conditions. From a framework design perspective, there is no such thing as an “exceptional condition”. Whether a condition is exceptional or not depends on the context of usage, — but reusable libraries rarely know how they will be used. For example, OutOfMemoryException might be exceptional for a simple data entry application; it’s not so exceptional for applications doing their own memory management (e.g. SQL server). In other words, one man’s exceptional condition is another man’s chronic condition.

Comments (18)

  1. Keivn Mullins says:

    Great explanation and I am looking forward to the second edition of the Framework Design Guidelines book.  Thanks for everything you have done!

    On a side note, I think you fat fingered From in the following sentence.

    Form a framework designed perspective, there is no such thing as an “exceptional condition”.

    Kevin

  2. Daniel Plaisted says:

    It looks like you misspelled "from" as "form".

  3. Roy J. Salisbury says:

    Should ..

    "Form a framework designed perspective"

    Be

    "From a framework designed perspective"

    Form to From

  4. Thanks! i fixed the typo.

  5. Maybe you should tell the CLR team as well 😉

    Reflection performance on the CLR is pretty embarassing compared with other managed runtimes (see the link on my name).

  6. Hey Krzysztof, the From sentence should also read: from a framework *design* perspective.

    Looking forward to the next book!

  7. I completely agree: exception are not exceptional at all!

    I like to split exceptions into 3 kinds: business/asynchronous/bug

    Once you defined the kind of an exception, it is much easier to decide what to code to handle it.

    http://www.codeproject.com/KB/books/guidelines_exception_cs.aspx

    Looking forward FDG v2!

  8. Luke, thanks! I fixed that too.

    Patrick, I think this is exactly what I already added to FDG. I just call the three kinds of errors: usage errors, program errors, and system failures.

  9. Jeroen, thanks for writing the post and pushing on the CLR team. I am doing the same thing — slowly 🙂

  10. Jay Bazuzi says:

    I have to admit that I’ve never really found a set of rules about how to use exceptions that I am completely comfortable with.

    One guideline I have tried to follow is "Exceptions should be exceptional *for the function that throws them*".  Of course you can’t know what context you’re being used in, but you do know what you’re intended to do.

  11. KBac says:

    Czesc Krzysztof! I like your annotation.

    I think you touched the hotspot here. As the definition of what condition is exceptional indeed remains in the eyes of the beholder.  

    Therefore if a subsystem is a class library one would expect many exceptions to propagate out -> hard to define what is critical and what should be handled == the usage context unknown.

    Service subsystem, would interpret exceptions thrown by libraries, translating them into more relevant business error hierarchy -> clear boundary defining specified usage context, now we know what is a system failure and what is a contingency error.

    Some more on failures / contingencies from Java universe:

    http://dev2dev.bea.com/pub/a/2006/11/effective-exceptions.html?page=1

  12. Michael Kapp says:

    Whether something is exceptional may depend on the context, but the very same is true for the "error condition". If a file is not found, this may be an error in one context, but a totally legal thing in another. So IMHO just exchanging the term "exception" with "error" does not really make it clearer when to use exceptions and when not.

    The usual justification for the guideline "use exceptions only in exceptional cases" is the performance penalty you get when a lot of exceptions are thrown, meaning it is motivated rather by the idiosyncrasies of the current CLR implementation than by design principles.

    And in fact, currently you cannot afford a low-level function that is called thousands of times during a mass operation and throws exceptions because it detects errors for the items it processes. In our project, the guideline is to use exceptions only if a programming error has been detected, and use error return information in other cases, especially in general-purpose functions that may be called frequently and from different contexts.

    I think it would be a good idea to improve the exception handling speed of .NET, so exceptions can be discussed independently of performance issues.

  13. David Nelson says:

    I agree with Michael. I much prefer programming with exceptions compared to error codes, due to the ability of exceptions to automatically propagate up the call stack, as well as the ability to pass along extra information. But currently there are too many cases where performance has to be considered.

  14. Claus Konrad says:

    I’m fully in sync. with this way of thinking. People unfortunately seems too afraid of the monster of Exceptions as somehing of a big bad wolf..

    Use them for the intended purpose – to communicate that the (server) was not able to fullfil the request made to it…

  15. Are you assuming the ability to ‘recover from an exception back to a pristine and valid state’ is not a key dimension here? I always thought it had to be germane to this topic.

    I’m clear when exceptions are the right choice, however it gets very foggy when I often see people over-extending their ‘ability’ to recover from exceptions I through in an assembly where I carefully implemented exceptions so they could be intelligently used, and most consumers catch ‘Exception’ and often just ignore it (to the horror of anyone here reading this of course).

    Here is a case I had recently:

    Consider in our library a deterministic algorithm that is rather picky if we lack any of a set of inputs (also correctly within ranges). The domain says it must fail, however it’s the domain specifying a failure but not going to the  next level of ‘crash the app’ when indeed we might have to.

    An exception is throw. ‘An exception was thrown due to our inability to service your request given the available contextual information’…

    1) OK we’re done. Let consumers decide just what recovery means, however in many cases it requires ‘white box’ knowledge of our internals to REALLY know that.

    2) How would we approach this as framework designers where indeed we’re corrupted and in spite of a demand for more power in making the final decision to ‘fail fast’, it’s more a balance. You can see where it goes wrong, as there would be an exception, then perhaps additional bits indicating to the consumer if ‘OK this is bad,,, you rally need to unload the appdomain’..

    3) I’ve never become 100% clear on just how far we can go in taking liberties as ‘providers of highly specific APIs’ as used in much larger and more general contexts.

    What I mean is it seems not always clear when we can indeed force the failure or allow the downstream consumer to decide.

    It’s easy of course if we happen to catch ‘out of memory’ but I mean more gray areas.

    Of course using CERs is a massive help along with declarative statements of just how far you could muck up an execution environment (grin)..

    Thoughts?

    Damon Wilder Carr

    http;//blog.domaindotnet.com/

  16. Hi,

    one argument is also that Exceptions not onlay are slower (in Java they are not really slow) , but that they also have somehow the same effect as goto’s.

    As we all know since Pascal, goto’s are to be avoided and therefore the same is true for exceptions 🙂

    Regards,

    Markus

  17. JB says:

    Sorry Markus, but I don't follow the logic in your last sentence.