My large application has this structure:
int main()
{
try {
...
} catch (std::exception& e) {
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
return 1;
}
}
Deep inside the call stack, various objects check their internal state, throwing std::runtime_exception
if they detect something bad. The all-inclusive exception handler catches it, prints some moderately useful info and terminates the program.
However, when I am debugging under MS Visual Studio, I could benefit from not having any exception handler: Visual Studio has its own, very useful, handler, which stops my application at the place where the exception is thrown, so I can examine what went wrong.
How can I do the catching of my exceptions conditionally?
I tried the following:
try {
...
} catch (std::exception& e) {
if (IsDebuggerPresent())
throw;
else
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
}
This gave a weird result: Visual Studio caught the exception that was rethrown and showed me the stack trace at the point where the exception was thrown. However, all objects in my application were apparently destructed, and I couldn't see e.g. local or member variables.
I could make the exception handler conditional on a compilation flag:
#ifdef NDEBUG
try {
#endif
...
#ifdef NDEBUG
} catch (std::exception& e) {
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
}
#endif
but this is inconvenient because I have to recompile everything if I want to debug it.
So, how can I make my exception handling conditional (depending on a command-line argument, for example)?
The order of catch statements is important. Put catch blocks targeted to specific exceptions before a general exception catch block or the compiler might issue an error. The proper catch block is determined by matching the type of the exception to the name of the exception specified in the catch block.
You have a two basic choices: Treat handle_exceptions as a boolean, and re-raise if False. Treat handle_exceptions as the exceptions to handle.
You can handle exceptions still without having catch blocks also, only thing you need to do is declare the throws clause in your method signature, so that the calling function would handle the exception. Before throwing exception, it executes the finally block.
So, how can I make my exception handling conditional (depending on a command-line argument, for example)?
By writing the code for it :o]
Consider this original code:
int main()
{
try {
run_the_application(); // this part different than your example
} catch (std::exception& e) {
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
return 1;
}
}
New code:
template<typename F>
int fast_run(F functor) { functor(); return EXIT_SUCCESS; }
template<typename F>
int safe_run(F functor)
{
try {
functor();
} catch (std::exception& e) {
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
template<typename F>
int run(const std::vector<std::string>& args, F functor)
{
using namespace std;
if(end(args) != find(begin(args), end(args), "/d"))
return fast_run(functor);
else
return safe_run(functor);
}
int main(int argc, char** argv)
{
const std::vector<std::string> args{ argv, argv + argc };
return run(args, run_the_application);
}
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