How should one log when an exception is triggered?

前端 未结 1 1264
时光取名叫无心
时光取名叫无心 2020-12-20 18:13

In a program I recently wrote, I wanted to log when my \"business logic\" code triggered an exception in third-party or project APIs. ( To clarify, I want to log when use o

相关标签:
1条回答
  • 2020-12-20 18:38

    I have no comment on your method, but it seems interesting! I have another way that might also work for what you want, and might be a little more general-purpose. It requires lambdas from C++11 though, which might or might not be an issue in your case.

    It's a simple function template that accepts a lambda, runs it and catches, logs and rethrows all exceptions:

    template <typename F>
    void try_and_log (char const * log_message, F code_block)
    {
        try {
            code_block ();
        } catch (...) {
            log (log_message);
            throw;
        }
    }
    

    The way you use it (in the simplest case) is like this:

    try_and_log ("An exception was thrown here...", [&] {
        this_is_the_code ();
        you_want_executed ();
        and_its_exceptions_logged ();
    });
    

    As I said before, I don't know how it stacks against your own solution. Note that the lambda is capturing everything from its enclosing scope, which is quite convenient. Also note that I haven't actually tried this, so compile errors, logical problems and/or nuclear wars may result from this.

    The problem I see here is that it is not easy to wrap this into a macro, and expecting your colleagues to write the [=] { and } parts correctly and all the time might be too much!

    For wrapping and idiot-proofing purposes, you'll probably need two macros: a TRY_AND_LOG_BEGIN to emit the first line till the opening brace for the lambda and an TRY_AND_LOG_END to emit the closing brace and parenthesis. Like so:

    #define TRY_AND_LOG_BEGIN(message)  try_and_log (message, [&] {
    #define TRY_AND_LOG_END()           })
    

    And you use them like this:

    TRY_AND_LOG_BEGIN ("Exception happened!")  // No semicolons here!
        whatever_code_you_want ();
    TRY_AND_LOG_END ();
    

    Which is - depending on your perspective - is either a net gain or a net loss! (I personally prefer the straightforward function call and lambda syntax, which gives me more control and transparency.

    Also, it is possible to write the log message at the end of the code block; just switch the two parameters of the try_and_log function.

    0 讨论(0)
提交回复
热议问题