A good design is not to create a set of exception classes -
just create one per library, based on std::exception.
Adding information is fairly easy:
try {
...
}
catch( const MyEx & ex ) {
throw MyEx( ex.what() + " more local info here" );
}
And exception handlers have the information they need because they are exception handlers - only the functions in the try blocks can cause exceptions, so the handlers only need to consider those errors. And not you should not really be using exceptions for general error handling.
Basically, exceptions should be as simple as possible - a bit like logfiles, which which they should have no direct connection.
This has been asked before, I think, but I can't find it right now.