Exception-Handling Macros
(From Marius Bancila's Blog)
Confronted with repeated situations when they have to catch the same exeptions and handle them the same way, some developers resort to macros for avoiding repetitive code. The following is such an example.
#define TRACE_ERR(x) std::cerr << x << std::endl #define TRY_CALL try #define CATCH_CALL catch(std::runtime_error const & e) \ {\ TRACE_ERR(std::string("runtime error: ") + e.what());\ }\ catch (std::logic_error const & e) \ {\ TRACE_ERR(std::string("logic error: ") + e.what());\ }\ catch (std::exception const & e) \ {\ TRACE_ERR(std::string("exception: ") + e.what());\ }\ catch (...)\ {\ TRACE_ERR("unexpected error");\ } void func_that_throws() { throw std::runtime_error("an error has occurred!"); } int main() { TRY_CALL { func_that_throws(); } CATCH_CALL }
If you execute this program it will print runtime error: an error has occurred!. However, these macros are not debugable, and in practice may even be hard to write. This example can be rewritten to use a regular function as handler for multiple exceptions. The only difference in the main() function is an additional call for this function, error_handler()
.
inline void trace_error(std::string_view text) { std::cerr << text << std::endl; } void error_handler() { using std::string_literals; try { throw; } catch (std::runtime_error const & e) { trace_error("runtime error: "s + e.what()); } catch (std::logic_error const & e) { trace_error("logic error: "s + e.what()); } catch (std::exception const & e) { trace_error("exception: "s + e.what()); } catch (...) { trace_error("unexpected error"); } } void func_that_throws() { throw std::runtime_error("an error has occurred!"); } int main() { try { func_that_throws(); } catch(...) { error_handler(); } }
The throw;
statement without an expression rethrows the currently handled exception. (It is allowed only when an exception is being handled, otherwise std::terminate()
will be called). It can be used to create handlers that can catch and handle multiple exception types without the need to duplicate code or resort to macros.