I have a pattern that repeats for several member functions that looks like this:
int myClass::abstract_one(int sig1) { try { return _original->abstract_one(sig1); } catch (std::exception& err) { handleException(err); } catch (...) { handleException(); } } bool myClass::abstract_two(int sig2) { try { return _original->abstract_two(sig2); } catch (std::exception& err) { handleException(err); } catch (...) { handleException(); } } [...] int myClass::abstract_n(bool sig3a, short sig3b) { try { return _original->abstract_n(sig3a, sig3b); } catch (std::exception& err) { handleException(err); } catch (...) { handleException(); } }
Where abstract one through n are methods of a pure virtual abstract interface for which myClass
and _original
are concrete implementations.
I don’t like that this pattern repeats in the code and would like to find a way to eliminate the repeating try
/ catch
pattern and code as a single abstraction, but I can’t think of a good way to do this in C++ without macros. I would think that there is a way with templates to do this better.
Please suggest a clean way to refactor this code to abstract out the repeated pattern.
Answer
I asked a very similar conceptual question, see Is re-throwing an exception legal in a nested ‘try’?.
Basically, you can move the various exception handlers to a separate function by catching all exceptions, calling the handler and rethrowing the active exception.
void handle() { try { throw; } catch (std::exception& err) { handleException(err); } catch (MyException& err) { handleMyException(err); } catch (...) { handleException(); } } try { return _original->abstract_two(sig2); } catch (...) { handle(); }
It scales well with more different exception kinds to differenciate. You can pack the first try .. catch(...)
into macros if you like to:
BEGIN_CATCH_HANDLER return _original->abstract_two(sig2); END_CATCH_HANDLER