在节目我最近写了,我想登录时,我的“商业逻辑”代码触发第三方或项目的API例外。 (为了澄清,我想时使用的API的导致异常。这可以是实际的上述许多帧登录throw
,并且可以是实际的下面许多帧catch
(其中可发生异常有效载荷的日志记录。))我做了以下内容:
void former_function()
{
/* some code here */
try
{
/* some specific code that I know may throw, and want to log about */
}
catch( ... )
{
log( "an exception occurred when doing something with some other data" );
throw;
}
/* some code here */
}
总之,如果发生异常,创建一个包罗万象的条款,记录错误,并重新抛出。 在我的心目中,这是安全的。 我知道一般捕获所有被认为是不好的,因为一个没有到异常的引用都得到任何有用的信息。 不过,我只是要重新把它,所以没有什么损失。
现在,对自己还不错,但一些其他的程序员修改了此方案,并结束了违反以上。 具体来说,他们把一个巨大的代码量进入试块在一种情况下,而在另一个去除“扔”,并放置在“回归”。
我现在我的解决办法是脆看; 它不是未来的修改防。
我希望有一个更好的解决方案,没有这些问题。
我有没有上述问题的另一种可能的解决方案,但我不知道别人怎么想的吧。 它采用RAII,特别是隐含触发如果“作用域退出”对象std::uncaught_exception
是不是真正的建筑,但是是真实的毁灭:
#include <ciso646> // not, and
#include <exception> // uncaught_exception
class ExceptionTriggeredLog
{
private:
std::string const m_log_message;
bool const m_was_uncaught_exception;
public:
ExceptionTriggeredLog( std::string const& r_log_message )
: m_log_message( r_log_message ),
m_was_uncaught_exception( std::uncaught_exception() )
{
}
~ExceptionTriggeredLog()
{
if( not m_was_uncaught_exception
and std::uncaught_exception() )
{
try
{
log( m_log_message );
}
catch( ... )
{
// no exceptions can leave an destructor.
// especially when std::uncaught_exception is true.
}
}
}
};
void potential_function()
{
/* some code here */
{
ExceptionTriggeredLog exception_triggered_log( "an exception occurred when doing something with some other data" );
/* some specific code that I know may throw, and want to log about */
}
/* some code here */
}
我想知道:
- 技术上,将这项工作有力? 最初,它似乎工作,但我知道有关于使用一些需要注意
std::uncaught_exception
。 - 有另一种方式来完成我想要什么?
注 :我已经更新了这个问题。 具体来说,我有:
- 添加的
try
/catch
,最初失踪,周围的log
函数调用。 - 添加跟踪
std::uncaught_exception
施工状态。 这可以防止其中被触发的异常堆栈回卷的一部分,另一析构函数的一个“尝试”块内创建该对象的情况。 - 固定新的“potential_function”创建一个名为对象,而不是临时对象如前。