有没有一种方法可以判断程序正在抛出异常

Is there a way to tell that the program is in process of throwing an exception?

本文关键字:判断 程序 抛出异常 方法 一种 有没有      更新时间:2023-10-16

我的问题的简短版本

堆栈上分配了一个类型为A的对象。在它的析构函数~A()中,有没有一种方法可以判断析构函数被调用是因为抛出了异常并且堆栈正在展开,还是仅仅因为定义它的范围"自然"结束?我试着检查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块中的一个单独的try块,然后重新throw,但这看起来很难看。

我尝试在析构函数中检查std::current_exception,但它为null,即使我们正在抛出异常。

没有标准的可移植方法可以像您描述的那样检测堆栈展开的状态。

但有一个更简单的解决方案。向MyTimeTracker添加一个布尔成员,如果API成功,则设置该成员,然后在析构函数中检查该成员。

MyTimeTracker::MyTimeTracker()
{
...
success = false;
}
MyTimeTracker::~MyTimeTracker()
{
...
if (!success) {
... 
}
}
void MyApi()
{
try
{
MyTimeTracker mtt;
//do API stuff
mtt.success = true;
}
catch (...)
{
//handle 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
}
}