I am using the following C code from the boost library :
try{
child c(commandString, (std_out & std_err) > pipe_stream);
} catch(process_error &pe){
cout<<pe.what()<<" second line"<<endl;
}
The commandString is a command like ls
or any other command. But if a command that does not exist is typed as per the documentation it throws the process_error
exception.
I am catching the exception here but not sure if there is a better way to print out the details of the exception or error than pe.what()
above?
CodePudding user response:
If you look at the boost reference about boost::process::process_error
, you can read this:
struct process_error : public system_error { };
It merely inherits std::system_error but can then be distinguished in the catch-block from other system errors.
emphasis mine
If you look then at the std::system_error
reference, like all other standard exceptions, what()
is the way to provide detailed information about the raised error so I would say yes, this is the proper way to print out the exception details.
But since boost::process::process_error
does not override the what()
function, it would return the same as a std::system_error
would.
CodePudding user response:
An alternative interface is using std::error_code
.
There are pros and cons:
PRO: it enables you to get more detail about where an error condition arose. (This is a hypothetical difference because it's not specified whether
what()
may include info beyond an error condition)CON: it might not get as much detail as in the exception message
CON: since some errors are exceptional, it's harder to express the possible error conditions in the interface: the error conditions get in the way in a way that exceptions do not
in your code you might have created this problem by handling exceptions: now how do decide what value(s) to return
NEUTRAL: you may still have to handle exceptions because exceptions can arise from any related code (e.g. during setup, doing allocations).
NEUTRAL: the
code()
member ofboost::process::process_error
is likely to be 100% identical to theerror_code
that you get
Demo
Contrast the implementations and output below:
#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";
}
Prints
Using error_code: Cannot spawn child process: No such file or directory
-1
Using exceptions: Exception: execve failed: No such file or directory
-1