如何正确捕获std和boost异常

How to properly catch std and boost exceptions

本文关键字:boost 异常 std 何正确      更新时间:2023-10-16

请告诉我如何正确使用try/catch与boost::exception。

这是其中一个例子

void Settings::init(const std::string &filename)
{
    using boost::property_tree::ptree;
    try 
    {
        read_xml(filename, pt);
    }
    catch(boost::exception const&  ex)
    {
        LOG_FATAL("Can't init settings. %s", /* here is the question */);
    }
}

我也需要catch std::exception吗?我不能让我的应用程序失败,所以我只需要记录所有内容。

乌利希期刊指南:我现在也无法理解从异常中检索日志信息??

std::exception有一个名为what()的成员函数,该函数返回一个const char*可以解释发生的事情。如果您想记录它(猜测LOG_FATAL以某种方式包装printf),您可以这样做:

catch(std::exception const&  ex)
{
    LOG_FATAL("Can't init settings. %s", ex.what());
}

对于boost::exception,您可以使用boost::get_error_info来了解更多关于它的信息

现在回答可能太晚了…但

        <...snip...>
        catch (const boost::exception& e)
        {
            std::string diag = diagnostic_information(e);
            // display your error message here, then do whatever you need to, e.g.        
            LOG_FATAL("Can't init settings. %s", diag);
        }
        <...snip...>

与任何c++一样,以下通用规则适用:

捕捉所有可能抛出的异常,并且只有在可以有意义地响应它们时才捕捉

您可以捕获所有其他异常(...),并创建一个日志消息或类似的东西,但随后您必须重新抛出它们(throw;)。如果在代码中除了中止某些操作之外什么也做不了,那么就不需要处理异常。让它冒泡到一个可以被有意义地使用的地方。

在您的代码中,您必须至少允许内存分配错误(std::bad_alloc),因此您可以检查这些错误,如果有意义的话。但是,如果你不知道你钓到的是什么,那么你对你钓到的东西就无能为力了。

说你的"程序不能失败"只能意味着这么多。最终,如果在顶级数据结构中出现了分配错误,那么就无能为力了。我能想到的最好的情况是,如果你的main函数在循环中处理一些数据;在这种情况下,你可以在循环中放置一个通用的try块,在出现异常的情况下,你可以继续进行下一轮。但我认为这是能够"有意义地处理异常"的一个实例,所以这只是上面的一个特殊情况。一般来说,虽然您可能希望将整个main函数包装在try块中,但您必须接受这样的事实:在最终的全面捕获情况下,您没有太多选择,只能中止程序。

这取决于你在try块中运行的代码。如果read_xml中的代码可能抛出std::异常,那么最好也捕获std::异常。如果你不确定,那么抓住他们两个也无妨。

如果您真的想做一些与特殊异常类型相关的事情,您应该只catch特殊异常类型。否则就使用std::exception。如果你的代码可能会抛出不同的东西,那就捕获...,或者在std::exception之后。

如果你想处理多个(特殊的)异常类型,那么你需要首先处理最显式的异常。