有没有办法告诉程序正在抛出异常?
Is there a way to tell that the program is in process of throwing an exception?
我的问题的简短版本
堆栈上分配了一个 A 类型的对象。在它的析构函数 ~A() 中,有没有办法判断析构函数是否因为抛出异常和堆栈正在展开而被调用,或者仅仅是因为定义它的范围结束 'naturally'?我尝试检查 std::current_exception
是否不为空,不起作用。
更长的版本
我有一个老API我要支持:
void MyApi()
{
try
{
MyTimeTracker mtt;
//do API stuff
}
catch(...)
{
//handle exception
}
}
如果API stuff
抛出异常,说明API失败,否则说明成功。 MyTimeTracker 检查 API stuff
的执行时间——它测量构造函数中的开始时间和析构函数中的结束时间,并将其报告给数据库。
现在我希望它也报告 API 调用是否成功。有没有办法在析构函数中告诉它?
我不允许在第一个 try
块之外分配它,因为整个 API 代码必须在 try 块中。我可以将 API stuff
放入第一个内部的单独 try 块中,然后重新抛出,但这看起来很难看。
我尝试在析构函数中检查 std::current_exception
,但它是空的,即使我们正在抛出异常。
没有像您描述的那样检测堆栈展开状态的标准便携方法。
但是有一个更简单的解决方案。在MyTimeTracker
中添加一个布尔成员,如果API成功则设置它,然后在析构函数中检查它。
MyTimeTracker::MyTimeTracker()
{
...
success = false;
}
MyTimeTracker::~MyTimeTracker()
{
...
if (!success) {
...
}
}
void MyApi()
{
try
{
MyTimeTracker mtt;
//do API stuff
mtt.success = true;
}
catch (...)
{
//handle exception
}
}
更新:
the main reason for doing all that is to report back the error code, which sits on the exception.
那你得求助于第二个try/catch
获取错误代码,将它存储在mtt
对象中以在析构函数中进行操作,然后重新抛出:
MyTimeTracker::MyTimeTracker()
{
...
errCode = 0;
}
MyTimeTracker::~MyTimeTracker()
{
...
if (errCode != 0) {
...
}
}
void MyApi()
{
try
{
MyTimeTracker mtt;
try
{
//do API stuff
}
catch (const the_api_error &e)
{
mtt.errCode = ...; // error code from e...
throw;
}
}
catch (...)
{
//handle exception
}
}
我的问题的简短版本
堆栈上分配了一个 A 类型的对象。在它的析构函数 ~A() 中,有没有办法判断析构函数是否因为抛出异常和堆栈正在展开而被调用,或者仅仅是因为定义它的范围结束 'naturally'?我尝试检查 std::current_exception
是否不为空,不起作用。
更长的版本
我有一个老API我要支持:
void MyApi()
{
try
{
MyTimeTracker mtt;
//do API stuff
}
catch(...)
{
//handle exception
}
}
如果API stuff
抛出异常,说明API失败,否则说明成功。 MyTimeTracker 检查 API stuff
的执行时间——它测量构造函数中的开始时间和析构函数中的结束时间,并将其报告给数据库。
现在我希望它也报告 API 调用是否成功。有没有办法在析构函数中告诉它?
我不允许在第一个 try
块之外分配它,因为整个 API 代码必须在 try 块中。我可以将 API stuff
放入第一个内部的单独 try 块中,然后重新抛出,但这看起来很难看。
我尝试在析构函数中检查 std::current_exception
,但它是空的,即使我们正在抛出异常。
没有像您描述的那样检测堆栈展开状态的标准便携方法。
但是有一个更简单的解决方案。在MyTimeTracker
中添加一个布尔成员,如果API成功则设置它,然后在析构函数中检查它。
MyTimeTracker::MyTimeTracker()
{
...
success = false;
}
MyTimeTracker::~MyTimeTracker()
{
...
if (!success) {
...
}
}
void MyApi()
{
try
{
MyTimeTracker mtt;
//do API stuff
mtt.success = true;
}
catch (...)
{
//handle exception
}
}
更新:
the main reason for doing all that is to report back the error code, which sits on the exception.
那你得求助于第二个try/catch
获取错误代码,将它存储在mtt
对象中以在析构函数中进行操作,然后重新抛出:
MyTimeTracker::MyTimeTracker()
{
...
errCode = 0;
}
MyTimeTracker::~MyTimeTracker()
{
...
if (errCode != 0) {
...
}
}
void MyApi()
{
try
{
MyTimeTracker mtt;
try
{
//do API stuff
}
catch (const the_api_error &e)
{
mtt.errCode = ...; // error code from e...
throw;
}
}
catch (...)
{
//handle exception
}
}