【问题标题】:How to add info to a std::exception using boost exception如何使用 boost 异常向 std::exception 添加信息
【发布时间】:2014-11-03 17:46:42
【问题描述】:

Boost Exception 框架很棒。您可以在应用程序的适当级别将信息添加到源自std::exceptionboost::exception 的异常,如in the documentation 所述。

但是如果你不控制代码中的 throw 站点,如何添加这些信息,例如标准库抛出异常,例如地图抛出超出范围?

不能被捕获为 boost::exception,因为它不是从它派生的:

try {
  my_map.at(id);
} catch(boost::exception &e) { // NOT caught
  e << errinfo_desc("id not found, map out of range");
  throw;
}

它可以被捕获为 std::exception,因为 out_of_range 派生自 std::exception,但随后可以添加 no 信息,因为它不是 boost::exception:

try {
  my_map.at(id);
} catch(std::exception &e) {
  // compile error: e << errinfo_desc("id not found, map out of range"); 
  throw;
}

捕获std::exception 并抛出一个新的boost::exception 丢失不想要的异常的原始位置:

try {
  my_map.at(id);
} catch(std::exception &e) {
  BOOST_THROW_EXCEPTION(my_exception() 
                        << errinfo_desc("id not found, map out of range")); 
}

是否可以保留原始异常及其位置等,并且以后仍然可以添加更多信息?怎么样?

【问题讨论】:

  • 不,不可能做你想做的事。
  • 除了我最后一种捕获 std::exception 并抛出 boost::exception 的方法之外,还有其他/更好的解决方法,还是我能做的最好的?
  • @JoachimPileborg 也许可以做他想要的(谁知道)。只是不是他要求的:)
  • 好吧,我所要做的就是在发生异常时尽可能多地收集所有不同级别的信息,基本上如 Boost Exception 所述。 @JoachimPileborg 如果您将评论变成答案,我会接受。

标签: c++ exception boost


【解决方案1】:

您可以通过捕获这两种情况来做到这一点:boost::exceptionstd::exception

try {
    my_map.at(id);
} catch(boost::exception &e) { 
    // If already a boost exception, catch here and add information
    e << errinfo_desc("id not found, map out of range");
    throw;
} catch(std::exception &) {
    // Otherwise, catch here and convert to a boost exception
    try { boost::rethrow_exception( boost::current_exception() ); }
    catch( boost::exception& e ) { 
      e << errinfo_desc("id not found, map out of range"); 
      throw; 
    }    
}

如果发现写这么多代码很痛苦,所以我问是否有更简洁的方法:Adding error_info to std::exception

【讨论】:

    【解决方案2】:

    就个人而言,我尽可能使用std::exception 层次结构。当它们还不够时,我只是从std::exception 派生我的异常类。 boost::exception 从来没有任何用例(也许我所有的代码都太简单了,不知道)。

    但如果你真的想将两者结合起来,这里有个疯狂的想法:使用多重继承。代码草图(未经测试,更像伪代码):

    // two personalities in one exception object
    class MyException: public std::exception, public boost::exception {
      explicit MyException(const std::exception& stdex) { ... }
      ... other ctors as needed...
    
      ... other stuff ...
    };
    
    ...
    
    try {
      my_map.at(id);
    } catch (const std::exception& stdex) {
      MyException myex(stdex); // gets SOME of the std::exception information
      myex << errinfo_desc("id not found, map out of range"); // boost::exception goodies
      throw myex;
    }
    

    明显的警告:使用 std::exception 引用初始化 MyException 对象时出现切片问题。以及 MI 的常见问题。您已被警告 :-)

    【讨论】:

      猜你喜欢
      • 2011-08-29
      • 1970-01-01
      • 2011-02-18
      • 2010-09-08
      • 1970-01-01
      • 2010-09-25
      • 2012-12-12
      • 1970-01-01
      • 2012-04-13
      相关资源
      最近更新 更多