I'm looking for a definition of 'exceptional' in terms of unit testing or OOP principles. Several times on SO when talking about exception throwing, I've seen comments like, "Well, I wouldn't consider getting Foo from Bar to be exceptional." (Is there a trollface emoticon?)
I did some googling and an answer wasn't immediately forthcoming. Are there any good definitions, rules of thumb, or guidelines that are more objective than opinion or preference? If one person says "this is exceptional" and another says "no, it isn't", how does one resolve this dispute?
Edit: Wow, so there are a number of answers already, with comments that disagree, and they all seem to be the opinion of the answerers :P Nobody's referenced a wikipedia page or an article a snippet from a greybeard. The 'meta-answer' I'm taking from this is there is no agreed-upon rule of thumb for when to use exceptions. I feel more confident employing my own, personal, idiosyncratic rules when choosing to throw exceptions.
When someone rips out the power chord, that is exceptional, most of the other situations are expected.
Well, Exceptional programming case is one which deviates the program flow from normal stream and it might be due to:
::A h/w of s/w fault that programmer cannot handle in given situation. Programmer may be not sure what to do in those case and he left it to the user or tool/library which invokes this code. ::Even programmer might not be sure the exact environment in which his code will be used and hence it is better to leave the error handling to the one who uses the code.
So exceptional case with a program might be is to use it uncommon environment or with uncommon interactions. Again uncommon interactions and unknown environments refers to the designers point of view. So deviation from Normal is exceptional and again it is based on the point of view and context of the programmer.
Is it too round and round?:D
Exceptions are useful when something has gone wrong that's outside the immediate scope of the problem. They should almost never be caught close to where thrown, since if they can be satisfactorily handled there they can be satisfactorily handled without throwing anything.
One example is C++'s containers, which can throw
bad_alloc
if they can't get the memory they need. The people who wrote the container have no idea what should happen if the container can't get memory. Perhaps this is an expected thing, and the calling code has alternatives. Perhaps this is recoverable. Perhaps this is fatal, but how should it be logged?Yes, it's possible to pass back error codes, but will they be used? I see lots of C memory allocations without tests for NULL, and printfs that just discard the return value. Moreover, lots of functions don't have a distinguishable error code, like negative for printf and NULL for memory allocation. Where any return value can be valid, it's necessary to find a way to return an error indication, and that leads to more complication than most programmers are willing to deal with. An exception cannot be ignored, and doesn't require lots of defensive code.
It's exceptional if:
It is a failure condition. AND
It happens infrequently and unexpectedly. AND
There is no better mechanism for reporting it.
edit
Stealing blatantly from Dan Weinreb's blog entry, which Ken posted about here, I'd like to offer the following summary of what exceptions are about.
The method's contract defines how (and whether) unusual conditions (ie. failures) are signaled. If the method says something is an exception, it just is. Of course, this leaves open the question of how we should design the contract.
Exceptions have the benefit of not requiring any checking by the caller, as well as naturally bubbling up until they are caught by something able to handle them. They can also contain significant detail, user-readable text and stack traces. These features make them ideal for failure cases that prevent further processing but are not predictable or common, or where explicit error-handling would be disruptive to code flow. They are especially good for errors that "should never happen" but are catastrophic in effect (such as a stack overflow).
Flags, error codes, magic values (NULL, nil, INVALID_HANDLE, etc.) and other return-based mechanisms do not commandeer flow, and are therefore better suited for cases that are common and best handled locally, especially those where the failure can be worked around. As they operate by convention and not fiat, you cannot count on them to be detected and handled, except that an invalid value may be designed to cause an exception if actually used (such as an INVALID_HANDLE being used to read).
When using exceptions in robust code, each method should catch unexpected exceptions and wrap them inside an exception from the contract. In other words, if your method does not promise to throw NullReferenceException, you need to catch it and rethrow it inside something more general or specific. They're called exceptions, not surprises!
IMHO, an exception should be thrown, if the further execution of program would result in fatal error or unpredictable behaviour.
Personally, I think that this kind of discussion is a pure waste of time and that "what is exceptional" is the wrong question to ask.
Exceptions are just another flow control mechanism with certain advantages (flow of control can pass multiple levels up the call stack) and disadvantages (somewhat verbose, behaviour is less localized).
Whether it's the right choice should not be determined by its name. Would we have these discussions if exceptions were simply called "bubbleups" instead?