I have these two functions, with duplicated exception treatment, which has the sole purpose of displaying an error message:
void func1() noexcept {
try {
do_task();
do_another_task();
} catch (const std::out_of_range& e) {
show_msg("Out of range error", e.what());
} catch (const std::logic_error& e) {
show_msg("Logic error", e.what());
} catch (const std::system_error& e) {
show_msg("System error", e.what());
} catch (const std::runtime_error& e) {
show_msg("Runtime error", e.what());
} catch (const std::exception& e) {
show_msg("Generic error", e.what());
}
}
void func2() noexcept {
try {
do_something();
do_something_else();
do_even_more();
} catch (const std::out_of_range& e) {
show_msg("Out of range error", e.what());
} catch (const std::logic_error& e) {
show_msg("Logic error", e.what());
} catch (const std::system_error& e) {
show_msg("System error", e.what());
} catch (const std::runtime_error& e) {
show_msg("Runtime error", e.what());
} catch (const std::exception& e) {
show_msg("Generic error", e.what());
}
}
I could just handle std::exception
and show a single generic message, but I want to be more specific, that's why I'm catching all possible exceptions.
I want to reuse this exception treatment code. I thought about this:
void run_treated(std::function<void()> func) noexcept {
try {
func();
} catch // ... all the catches go here
}
void func1() noexcept {
run_treated([]()->void {
do_task();
do_another_task();
});
}
void func2() noexcept {
do_something();
do_something_else();
do_even_more();
}
run_treated
will be called a lot. Should I be concerned about performance?Java provides two different options to handle an exception. You can either use the try-catch-finally approach to handle all kinds of exceptions. Or you can use the try-with-resource approach which allows an easier cleanup process for resources.
The C programming language does not support exception handling nor error handling. It is an additional feature offered by C. In spite of the absence of this feature, there are certain ways to implement error handling in C. Generally, in case of an error, most of the functions either return a null value or -1.
There are two different methods or functions in C, which are used to display the error message instead of just displaying the errno as we did it in the above program.
Example: Exception handling using try...In the example, we are trying to divide a number by 0 . Here, this code generates an exception. To handle the exception, we have put the code, 5 / 0 inside the try block. Now when an exception occurs, the rest of the code inside the try block is skipped.
There's the option of using a Lippincott Function to centralize the exception handling logic. Consider this:
void Lippincott () noexcept {
try {
throw;
} catch (const std::out_of_range& e) {
show_msg("Out of range error", e.what());
} catch (const std::logic_error& e) {
show_msg("Logic error", e.what());
} catch (const std::system_error& e) {
show_msg("System error", e.what());
} catch (const std::runtime_error& e) {
show_msg("Runtime error", e.what());
} catch (const std::exception& e) {
show_msg("Generic error", e.what());
}
}
void func1() noexcept {
try {
do_task();
do_another_task();
} catch (...) {
Lippincott();
}
}
void func2() noexcept {
try {
do_something();
do_something_else();
do_even_more();
} catch (...) {
Lippincott();
}
}
How does it work? When you enter the handler in func1
or func2
there is a "current exception" being processed. The body of Lippincott
starts a new try..catch block and re-throws it. Then it catches the appropriate exceptions and handles them accordingly in a centralized manner.
You should also note that your exception handling logic isn't really noexcept
. There could theoretically be exceptions not covered by your list. In which case there are several places for std::terminate
to be called, depending on how you mark things noexcept
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With