登录异常构造函数是不好的做法吗?
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 不受记录器的依赖,这也是好东西。
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 不受记录器的依赖,这也是好东西。