Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch exceptions conditionally?

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)?

like image 775
anatolyg Avatar asked Mar 10 '15 13:03

anatolyg


People also ask

How do you catch specific exceptions?

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.

How can you conditionally raise and handle an exception during debugging Python?

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.

How do you catch exceptions without trying?

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.


1 Answers

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);
}
like image 69
utnapistim Avatar answered Oct 03 '22 03:10

utnapistim