有没有办法告诉程序正在抛出异常?

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
    }
}