
<snip> It is great that a filename can be associated with an exception thrown at a lower level that didn't know that information. Yet, the additional information is purely optional. There is no guarantee that the rethrower ever added the information. As such the final catcher will have to do a lot of tests to see if the information exists.
There is no guarantee in general, meaning that you can't write a universal final catcher that deals with exceptions regardless of what they are, what context they were created in, and what contexts they passed through. However, catchers don't need to be universal. Consider this example of 3 contexts: 1) Mid-level code opens a file, creates a serializer object, and calls a low-level library to read something. 2) The low-level lib throws an exception without a file name because it's using the serializer object, which in principle could be reading from some non-file source. 3) High-level code catches the exception and handles it. In this scenario, 3) doesn't need to deal with exceptions that lack a file name, because the mid-level context should add it (if a file name is missing, we have a bug.) A reasonable behavior is to assert in this case. In principle it is possible that at 3) we catch an exception that legitimately lacks a file name, but that simply means that it did not pass through 1). Still, the solution doesn't need to be universal. At some point, someone needs to "know" about all possible exceptions that can reach a particular high-level exception-handling context, and handle them.
However, it doesn't seem to do anything to get me one step closer of generating a stack trace when the exception is thrown or at least when the boost::exception is constructed.
Stack traces can be stored in boost::exception just as any other error_info. If a particular compiler/platform provides an interface for obtaining a stack trace, I don't see why it shouldn't be captured and stored in the exception by the boost::exception constructor.
There are no callbacks/hooks to add this capability to everything that derives from boost::exception when the data is not optional. It is not good enough for such stack trace and potential other information to sometimes be there as it is information that should always be available.
If some information is not required at the point of the throw, but is required at the point of the catch, you assert() on get_error_info. If some information is required at the point of the throw, then you make your exception class' constructor take that information as argument(s).
It is as specialized as my wish and maybe doesn't deserve the name boost::exception. Maybe it should be renamed to boost::map_exception, boost::tuple_exception, boost::additional_optional_information_exception or something similar and in the future an exception class that provides stack traces can be called boost::stacktrace_exception. Let's keep, reserve, the word boost::exception for the day when it handles most everyone basic exception needs; both sets of functionality.
std::exception does not solve all of your problems either, but it does "deserve" its name because it's purpose is to be the universal base class of all exceptions. boost::exception can be viewed as an extension of std::exception which adds an important piece of missing functionality. If you feel that boost::exception lacks other important functionality to "deserve" its ambitions to be the universal base class of all boost exceptions, the solution is not to rename boost::exception, but to add the missing functionality. Emil Dotchevski