There is a lot of relativity involved in working with exceptions. Beyond low level APIs where exceptions cover errors raised from hardware and the OS there is a shady area where the programmer decides what constitutes an exception and what is a normal condition.
How do you decide when to use exceptions? Do you have a consistent policy regarding exceptions?
C++ exception handling is built upon three keywords: try, catch, and throw. throw − A program throws an exception when a problem shows up. This is done using a throw keyword. catch − A program catches an exception with an exception handler at the place in a program where you want to handle the problem.
Exceptions should not be used as a method of passing information internally between methods inside your object, locally you should use error codes and defensive programming.
Exceptions are designed to pass control from a point where an error is detected to a place (higher up the stack) where the error can be handled, presumably because the local code does not have enough context to correct the problem and something higher up the stack will have more context and thus be able to better organize a recovery.
When considering exceptions (in C++ at least) you should consider the exception guarantees that your API makes. The minimum level of guarantee should be the Basic guarantee though you should strive (where appropriate) to provide the strong guarantee. In cases where you use no external dependencies from a articular API you may even try to provide the no throw guarantee.
N.B.Do not confuse exception guarantees with exception specifications.
There is no guarantee about the state of the object after an exception escapes a method In these situations the object should no longer be used.
In nearly all situations this should be the minimum guarantee a method provides. This guarantees the object's state is well defined and can still be consistently used.
This guarantees that the method will completely successfully Or an Exception will be thrown and the objects state will not change.
The method guarantees that no exceptions are allowed to propagate out of the method. All destructors should make this guarantee.
| N.B. If an exception escapes a destructor while an exception is already propagating
| the application will terminate
This blog entry from Eric Lippert, a Senior Software Design Engineer at Microsoft, sums up an excellent and brief set of exception strategy guidelines.
In short:
Fatal: Terrible errors that indicate your process is totally unrecoverable. Clean up whatever resources you can, but don't catch them. If you're writing code that has the ability to detect such a situation, by all means, throw. Example : Out of memory exception.
Boneheaded: Relatively simple errors that indicate your process can't operate on whatever data it's being handed, but would continue on normally if whatever situation caused the error is simply ignored. These are better known as bugs. Don't throw or catch them, but instead prevent them from happening, usually by passing errors or other meaningful indicators of failure that can be handled by your methods. Example: Null argument exception.
Vexing: Relatively simple errors that code you don't own is throwing at you. You must catch all of these and deal with them, usually in the same way as you would deal with a Boneheaded exception of your own. Please don't throw them right back out again. Example: Format exception from C#'s Int32.Parse() method
Exogenous: Relatively straightforward errors that look a lot like Vexing (from other people's code) or even Boneheaded (from your code) situations, but must be thrown because reality dictates that the code that's throwing them really has no idea how to recover, but the caller probably will. Go ahead and throw these, but when your code receives them from elsewhere, catch them and deal with them. Example: File not found exception.
Of the four, the exogenous ones are the ones that you have to think about most to get right. An exception indicating a file is not found is appropriate to throw for an IO library method, in that the method almost certainly will not know what to do should the file not be found, especially given that the situation can occur at any time and that there is no way to detect whether or not the situation is transient. Throwing such an exception would not be appropriate for application-level code, though, because that application can get information from the user on how to proceed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With