登录异常构造函数是不好的做法吗?

Is logging in an exception constructor bad practice?

1.) 什么样的异常日志记录是更好的做法?

           //1 xor //2

2.) 这个问题是针对特定语言的吗? (对c++最感兴趣)

到代码:

:: LOG 是单例记录器的宏

struct myExc : virtual std::runtime_error
{
    myExc( std::string const&msg )
    :runtime_error(msg)
    {
        LOG << msg;    //1
    }
};

void foo_throw()
{
   throw myExc("");
}


/// some_where
...
try()
{
    foo_throw();
}
catch( myExc const& e)
{
    LOG << e.what();     //2
}
catch(...

第二种变体更可取,因为调用堆栈更上层的一些代码可以选择捕获异常而不输出错误。在第一个版本中,您会在创建异常时立即输出,从而减少捕获代码的选择。

例如,您可以这样做:

try
{
    foo_throw();
}
catch (myExc& e)
{
    //do some recovery
}

如果您的异常构造函数输出了一些东西,那么在捕获该异常时您将无能为力。

第一个大概是'too smart'。你确定 LOG << 不能抛出异常吗?在第二种情况下,你有更多的信息和更多的可能性来考虑如果 LOG << 抛出会发生什么,特别是你可以在日志之前做强制性的安全事情。

第一种情况尝试做两件事:通知异常和记录消息。这是不好的。在第二种情况下,你只通知异常,然后处理它:做一些事情并记录。

第二种情况是责任分离的示例,其中一个 class 执行一项任务。

另外,您的例外 class 不受记录器的依赖,这也是好东西。