C++ 如何正确捕获 std 和 boost 异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8136534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:04:35  来源:igfitidea点击:

How to properly catch std and boost exceptions

c++boostloggingexception-handling

提问by nix

Please tell me how to use try/catch properly with boost::exception.

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

This is one of examples

这是例子之一

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 */);
    }
}

Do I need catch std::exception too? I can't let my application fail, so I just need to log everything.

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

UPD:I also can't understand now to retrive information for logging from exception???

UPD:我现在也无法理解从异常中检索日志信息???

采纳答案by Flexo

std::exceptionhas a member function called what()that returns a const char*that mightexplain what happened. If you want to log it (guessing that LOG_FATALwraps printfsomehow) you can do:

std::exception有一个叫做成员函数what()返回一个const char*可以解释发生了什么。如果你想记录它(猜测以某种方式LOG_FATAL包装printf)你可以这样做:

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

For boost::exceptionthough you can use boost::get_error_infoto find out more about it.

对于boost::exception虽然你可以使用boost::get_error_info以了解更多关于它。

回答by Mia Shani

probably WAY too late in answering... but

回答可能太晚了……但是

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

回答by Kerrek SB

As with any C++, the following universal rule applies:

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

Catch allexceptions that can possibly be thrown, and only ifyou can respond to them meaningfully.

捕获所有可能抛出的异常,并且仅您可以对它们做出有意义的响应时。

You can catch all other exceptions (...) as well and create a log message or something like that, but then you have to rethrow them (throw;). If there's nothing you can do in your code other than abort some operation, then you don't need to handle the exception. Let it bubble up to a place where it canbe used meaningfully.

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

In your code, you will have to allow at least for memory allocation errors (std::bad_alloc), so you could check for those, if that makes sense. But again, if you don't know what you're catching, there's not much you can do with what you catch.

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

Saying your "program cannot fail" can only mean so much. Ultimately, if you have an allocation error in a top-level data structure, there's nothing you cando. The best scenario I can imagine is if your main function processes some data in a loop; in that case, you can put a universal try block around the loop, and in case of an exception you just move on to the next round. But I would count that as an instance of being able to "handle an exception meaningfully", so that's just a special case of the above. In general, while you may want to wrap your entire main function in a try block, you'll just have to accept that in the ultimate catch-all case you don't have much of a choice but to abort the program.

说你的“程序不会失败”只能意味着这么多。最终,如果您在顶级数据结构中出现分配错误,您无能为力。我能想象的最好的情况是,如果您的主函数在循环中处理一些数据;在这种情况下,您可以在循环周围放置一个通用的 try 块,如果出现异常,您只需进入下一轮。但我会将其视为能够“有意义地处理异常”的一个实例,因此这只是上述情况的一个特例。一般而言,虽然您可能希望将整个 main 函数包装在 try 块中,但您只需要接受这一点,在最终的包罗万象的情况下,您别无选择,只能中止程序。

回答by obmarg

That depends on the code that you're running in the try block. If the code in read_xml could throw a std::exception then you would be better to catch std::exception as well. If you're unsure, then it can't really hurt to catch both of them.

这取决于您在 try 块中运行的代码。如果 read_xml 中的代码可以抛出 std::exception ,那么你最好也捕获 std::exception 。如果您不确定,那么抓住他们两个并不会真正受到伤害。

回答by 0xbadf00d

You should catchonly special exception types if you really want to do something related to that type. Otherwise just use std::exception. If you're code could throw something different, than catch ...instead or after std::exception.

catch如果您真的想做与该类型相关的事情,您应该只使用特殊的异常类型。否则只需使用std::exception. 如果你的代码可以抛出不同的东西,而不是 catch...或者 after std::exception

If you want to handle multiple (special) exception types than you need to handle the most explicit first.

如果要处理多个(特殊)异常类型,则需要先处理最明确的异常类型。