I try to use boost exceptions and fall. There are the problem code:
struct exception_base : virtual std::exception, virtual boost::exception
{
exception_base(std::exception&& e)
: std::exception(e)
{}
};
int main()
{
std::string exception_description;
try
{
BOOST_THROW_EXCEPTION(exception_base(std::runtime_error("hello exception")));
}
catch (exception_base& ex)
{
exception_description = boost::diagnostic_information(ex);
}
return 0;
}
In this case the value of the exception_description have the last string - "std::exception::what: Unknown exception". It is unexpected value. If I change BOOST_THROW_EXCEPTION to usual throw - the last string of exception_description value looks expected - "std::exception::what: hello exception"
So how to use BOOST_THROW_EXCEPTION correctly?
Your custom exception class is not necessary, and is the root cause of your problems. If you remove it you can just do this:
BOOST_THROW_EXCEPTION(std::runtime_error("hello exception"));
Then:
catch (const std::exception& ex)
And the code will work the way you expect.
Why was it not working before? Well, your exception_base
class has no storage for the error message, so when you construct it from a std::exception
it cannot store the message (e.g. from the original runtime_error
).
You could fix it a lot of different ways, but ultimately they will boil down to the same thing: if you want your custom exception class to contain a message string, it must somehow contain that message string.
I'm a fan of not defining custom exception types 95% of the time, so I'd advise you to just keep it simple and use runtime_error
(and/or logic_error
).
Note that BOOST_THROW_EXCEPTION
automatically adds boost::exception
as a base class for the thrown type, so you do not need to do that yourself anyway--there's no advantage.
other things:
std::cerr << boost::diagnostic_information(ex) << std::endl;
and that will print all the metadata that BOOST_THROW_EXCEPTION
adds on like: file, line, function, etcstd::exception
inside of the BOOST_THROW_EXCEPTION()
you can wrap your std::exception
with boost::enable_error_info()
to change the type to boost::exception
and that allows you to enrich the exception with other arbitrary fields via operator<<