如何在不同的上下文(例如线程)中保留原始异常类型信息?

时间:2016-05-16 09:12:38

标签: c++ c++11

作为{{1}}的{​​{3}}的后续,其中e是std :: exception_ptr,我想知道如何将原始异常信息保留在当前异常块之外?

在库中,我将exception_ptr实例保存在不同的地方,因此它(理论上)应该可以获得原始异常及其包含的所有信息,例如:在错误报告功能中。异常指针是在其中一个异常基类的catch子句中创建的,因此std :: make_exception_ptr只创建基类型异常的副本,而不是原始异常的副本(这是我在链接问题中看到的麻烦)。 / p>

存储引用当然是个坏主意(实际的异常对象很快就会消失)。存储异常的副本(通过基于类型)给出了相同的对象切片问题,就像使用std :: exception_ptr时一样。那么,我还有其他选择吗?

1 个答案:

答案 0 :(得分:-3)

Kerrek SB的第一条评论让我想到了如何解决这个问题。我没有从catched基类型创建exception_ptr实例,而是现在有一个函数重新抛出异常,并使用已知的子类从它们创建单独的异常指针,我可以保留它并获得我需要的信息:

INotifyPropertyChanged

然后调用此函数:

std::exception_ptr DefaultErrorStrategy::reportError(Parser *recognizer) {
  // If we've already reported an error and have not matched a token
  // yet successfully, don't report any errors.
  if (inErrorRecoveryMode(recognizer)) {
    return nullptr; // don't report spurious errors
  }

  beginErrorCondition(recognizer);

  std::exception_ptr result = nullptr;
  try {
    // We are called from catch() clauses, so we can just rethrow the current exception and catch
    // the original exception type, so we don't lose information (caused by object slicing).
    throw;
  } catch (NoViableAltException &ne) {
    result = std::make_exception_ptr(ne);
    reportNoViableAlternative(recognizer, ne);
  } catch (InputMismatchException &ne) {
    result = std::make_exception_ptr(ne);
    reportInputMismatch(recognizer, ne);
  } catch (FailedPredicateException &ne) {
    result = std::make_exception_ptr(ne);
    reportFailedPredicate(recognizer, ne);
  } catch (RecognitionException &ne) {
    result = std::make_exception_ptr(ne);
    recognizer->notifyErrorListeners(ne.getOffendingToken(), ne.what(), result);
  }
  return result;
}

<强>更新

我在错误的假设下创建了该代码(current_exception和make_exception_ptr做同样的事情 - &gt;创建一个副本)。事实并非如此,这个答案中的代码确实是错误的,我保留它仅供参考,如何做。