Is it possible to write a template function and pass it a list of exception types to handle?
I would like to implement something like this
template<class Exc1, Exc2>
auto foo()
{
try {
bar();
} catch (const Exc1& e) {
log_error(e);
} catch (const Exc2& e) {
log_error(e);
}
}
but have a variable number of exception types to handle.
The following would do what I need, but of course does not compile
template<class... Exceptions>
auto foo()
{
try {
bar();
} catch (const Exceptions& e...) {
log_error(e);
}
}
Why do I need this? I am writing a generic 'retry' mechanism that should call provided callable, retrying several times in case an exception from the list is thrown (but letting all other exceptions bubble up). Currently I bypass the problem by providing two callables: the target function and exception handler:
template<class Function, class ExceptionHandler>
auto retry(Function function, ExceptionHandler handler)
{
for (auto i = 0; i < 3; ++i) {
try {
return function();
} catch (...) {
handler();
}
}
return function();
}
auto f = [] {
// do something and possibly throw an exception
};
auto h = [] {
try {
throw;
} catch (const Exc1& e) {
log_error(e);
} catch (consy Exc2& e) {
log_error(e);
}
};
retry(f, h);
The above code works as I expect, but I was hoping for a more elegant solution.
you can try to use a recursion
template<class Exception, class... Exceptions>
auto foo()
{
if constexpr (sizeof...(Exceptions) == 0)
{
try {
bar();
} catch (const Exception& e) {
log_error(e);
}
}
else
{
try {
foo<Exceptions...>();
} catch (const Exception& e) {
log_error(e);
}
}
}