I have a class that manages resources. It takes a Loader class that can retrieve the resource from a path. Loader is an abstract base class, so anyone could make a new loader.
If a resource is requested that is not in the cache, the resource manager will request it from the loader. If the loader fails, resource manager throws an exception class I made called LoadingError.
I want the Loader class to throw exceptions when it fails. I can require them to inherit from my own exception base class if necessary.
The problem is, when LoadingError is thrown, I want it to include specific information about why it failed. But I don't know exactly what exceptions may be thrown by the Loader. (The user might, in his catch blocks around the resource manager).
Either I can throw only LoadingError with some general information, or allow a specific exception from Loader come out and not touch it. But I would like to catch the exception and bundle it in my own LoadingError exception, or point to it in LoadingError . But I don't know how long the pointed-to exception will last (concerned about bad pointer).
Which of the three should I do? (And how, for the third one..)
Thanks
How about a nested exception?
Just make a suitable class that stores the exception:
When the exception is caught, the catcher can rethrow the nested exception:
In fact, this entire logic is already provided by the standard library via
std::throw_with_nested
.When one can enforce use of one's own exception classes throughout the code, the simplest way to do nested exception is undoubtedly to just define a custom exception class that contains a
std::exception_ptr
, which can be obtained viastd::current_exception
, both declared by the<exception>
header.However, C++11 supports nested exceptions via the
std::nested_exception
class, and functions such asstd::throw_with_nested
. Thenested_exception
constructor picks up the ? current_exception()`, if any, and stores that as its nested exception. There's no way to specify the nested exception expclitly: it's always the current exception.This machinery also supports exception propagation through non-exception-aware code such as up through C callbacks, and it supports exceptions (and nested exceptions) of arbitrary classes, not just
std::exception
and derived classes.So, when e.g. library code uses this functionality, then it's desirable to be able to deal with such standard nested exceptions, and not just one's own custom (simpler to use but less general) scheme.
Sadly, as I'm writing this (Jan 2014) the Visual C++ compiler does not yet support
std::nested_exception
, although it does support much of the rest of the machinery. Happily, it's not difficult to define these things. E.g., googling it, I found working code at Tomaka-17's blog, and that's the code that I've adapted below --std::nested_exception
support for Visual C++:With g++ 4.7.2 it would be more involved to define this stuff, but since g++ 4.8.2 already has it it's not necessary: for g++ just upgrade the compiler if necessary.
Then the next problem is how to retrieve the nested exception information.
Essentially that boils down to iteratively rethrowing and catching each nested exception, e.g. as follows:
Output:
Disclaimer: I cooked up the above code for this answer, so it's not been extensively tested. But anyway, enjoy!