【问题标题】:Alternatives to using what() for exception details in boost在 boost 中使用 what() 获取异常详细信息的替代方法
【发布时间】:2021-11-24 17:31:40
【问题描述】:

我正在使用来自 boost 库的以下 C++ 代码:

try{

child c(commandString, (std_out & std_err) > pipe_stream);

} catch(process_error &pe){
    cout<<pe.what()<<" second line"<<endl;

}

commandString 是类似ls 的命令或任何其他命令。但是,如果根据文档键入不存在的命令,则会引发 process_error 异常。
我在这里发现了异常,但不确定是否有比上面的pe.what() 更好的方法来打印异常或错误的详细信息?

【问题讨论】:

  • 嗯,你显然可以打印commandString,但是......如果你没有说出你想要达到的目标或你已经说过的话,谁能说什么会“更好”得到?

标签: c++ exception boost


【解决方案1】:

如果您查看boost reference 关于boost::process::process_error,您可以阅读以下内容:

struct process_error : public system_error {
};

它仅继承 std::system_error,但随后可以在 catch-block 中与其他系统错误区分开来。

强调我的

如果您查看std::system_error reference,就像所有其他标准异常一样,what() 是提供有关所引发错误的详细信息的方法,所以我会说是的,这是打印出异常详细信息的正确方法.

但由于boost::process::process_error 不会覆盖what() 函数,它会返回与std::system_error 相同的结果。

【讨论】:

  • 我对你的最后一段感到困惑。矛盾是什么? “但是因为……”?
  • 我认为他们的观点是,如果 OP 不喜欢 system_error.what()process_error.what() 也不会更好。即,“.what() 是正确的,但你可能不会喜欢它。”
  • 那么在这方面 process_error::code() 在技术上是一种替代方案。或者,您当然可以使用我在回答中比较过的非抛出接口
【解决方案2】:

另一个接口是使用std::error_code

各有利弊:

  • PRO:它使您能够获得有关在哪里出现错误情况的更多详细信息。 (这是一个假设的差异,因为没有指定 what() 是否可能包含错误条件之外的信息)

  • CON:它可能没有异常消息中的详细信息

  • CON:由于某些错误是异常,因此在界面中表达可能的错误条件更加困难:错误条件以异常的方式阻碍不是

    在您的代码中,您可能通过处理异常产生了这个问题:现在如何决定返回什么值

  • 中性:您可能仍然需要处理异常,因为异常可能来自任何相关代码(例如,在设置期间、进行分配时)。

  • 中性:boost::process::process_errorcode() 成员可能与您得到的 error_code 100% 相同

演示

对比下面的实现和输出:

Live On Coliru

#include <boost/process.hpp>
#include <iostream>
namespace bp = boost::process;

int using_exceptions(std::string const& commandString) {
    try {
        bp::pstream pipe_stream;
        bp::child   c(commandString, (bp::std_out & bp::std_err) > pipe_stream);
        c.wait();
        return c.exit_code();
    } catch (std::exception const& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1; // WHAT TO RETURN
    }
}

int using_error_code(std::string const& commandString) {
    try {
        bp::pstream pipe_stream;
        std::error_code ec;

        bp::child c(commandString, (bp::std_out & bp::std_err) > pipe_stream,
                    ec);

        if (ec) {
            std::cerr << "Cannot spawn child process: " << ec.message() << "\n";
            return -1; // WHAT TO RETURN?
        } else {
            c.wait(ec);
            std::cerr << "Error: " << ec.message() << "\n";
            return c.exit_code();
        }

    } catch (std::exception const& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        return -1; // WHAT TO RETURN
    }
}

int main()
{
    auto cmd = "/usr/bin/bogus";
    std::cout << "Using error_code: " << using_error_code(cmd) << "\n";
    std::cout << "Using exceptions: " << using_exceptions(cmd) << "\n";
}

打印

Using error_code: Cannot spawn child process: No such file or directory
-1
Using exceptions: Exception: execve failed: No such file or directory
-1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多