The STLplus library throws exceptions to indicate that a component has been misused in some way. It never throws an exception during normal operation with the notable special case of the message_handler component which can throw the message_handler_limit_error exception during normal execution - read the documentation for message_handler to find out why and how to deal with it.
All exceptions used by STLplus are subclasses of std::exception, so all exceptions can be handled by simply catching this one superclass. In fact, all exceptions are subclasses of either std::logic_error and std::runtime_error.
Of course, instead of just catching std:exception, you can catch particular exceptions if there is any special handling to be performed on that particular exception.
For example, the following snippet of C++ handles the above-mentioned example of the message_handler's limit_error as a special case and then all other standard exceptions as a general case:
message_handler errors(std::cout, 10, true); try { // use the error handler } catch(message_handler_limit_error& exception) { // special handling of the error handler's limit_error } catch(std::exception& exception) { // general handling of std::exception and any of its derivatives } return errors.error_count();
Note that catching an exception by reference preserves the subclass information (see "The C++ Programming Language", Bjarne Stroustrup, ch14) so that dynamic casts could be used on a std::exception to get the subclass information.
In practice, exceptions should only be caught in one or two places in the program - the main task of exceptions is to detect programming errors during software development. The what() method of the exception returns a char* message containing a description of the problem. The STLplus-thrown exceptions always indicate which component threw the exception.
The idea is that you catch the exception - probably only in the main() function of the application - and print out the what() description. This will enable you to get a starting point for looking for the programming error that causes the exception to be thrown. In theory at least, release versions of software should not throw any exceptions (with the above-mentioned message_handler_limit_error being a notable special-case).
The philosophy here is to use C++ standard exceptions where they are appropriate (for example std::out_of_range for an index that's out of range of an array). If there isn't a standard exception that's appropriate, then the exception will be classed as general to the STLplus or specific to a component. General exceptions will be collected into a header exceptions.hpp whilst specific exceptions will be declared in the specific component's header - as is already the case for components like the message_handler and ntree.
The C++ standard includes a set of predefined exceptions, defined in the header <stdexcept>. The exceptions are all based on the superclass std::exception and form a sub-class hierarchy:
Note: those exceptions marked with a can be thrown themselves whereas those exceptions marked with a are never thrown themselves, but serve as intermediate classes in the hierarchy. You can catch these intermediate classes in which case you will catch all subclasses of them. For example, catching a runtime_error will catch any of range_error, overflow_error or underflow_error plus any other subclasses that may be defined in the future by either the standards committee or by you. It is good practice to catch the intermediate classes because your code will work correctly if new exceptions are added to the set.
There are two sub-groups of exception: logic_error and runtime_error. These represent two different concepts:
Exceptions used in STLplus that are common to more than one component are collected in header exceptions.hpp.
The following exceptions are defined for indicating errors in the use of STLplus iterators in the container classes (well, those that have iterators) and for indicating errors in smart pointers:
*
or ->
operators.