This question is getting old, but there is actually an elegant way to create such an exception boundary: create a function as the one proposed by @Tim Martin, then wrap the old code into lambdas that will be called by the exception boundary handle. Here it the excception boundary handle:
template<typename Callable>
auto exception_boundary_handle(Callable&& func, const std::string& msg=""s)
-> decltype(func())
{
try
{
return func();
}
catch( const Poco::Exception &e )
{
try{ LogCritical( Logs.System(), std::string( e.displayText() ).append( msg ) );}catch(...){assert(0);}
}
catch( const std::exception &e )
{
try{LogCritical( Logs.System(), std::string( e.what() ).append( msg ) );}catch(...){assert(0);
}
catch(...)
{
try{ LogCritical( Logs.System(), std::string( "Exception caught in " __FUNCTION__ ". " ).append( msg ) );}catch(...){assert(0);}
}
}
You can use it as follows:
int some_func(int eggs)
{
return exception_boundary_handle([&] {
// put the old code here,
// I filled it with pseudo-random stuff
eggs += 42;
return eggs;
},
"Extra error message if you ever need it");
}
Of course, since this is not a macro solution, you will have to add another parameter if you want to inject the __FUNCTION__ information into the handler:
template<typename Callable>
auto exception_boundary_handle(Callable&& func,
const std::string& msg=""s,
const std::string& func_name="")
-> decltype(func())
{
try
{
return func();
}
// ...
catch(...)
{
try{ LogCritical( Logs.System(), std::string( "Exception caught in "s + func_name + ". "s ).append( msg ) );}catch(...){assert(0);}
}
}