I recently found this legacy code that uses strerror() method to find out why a file operation failed instead of using the exception object.
try
{
boost::filesystem::path src(...);
boost::filesystem::path dst(...);
boost::filesystem::copy_file(src, dst);
}
catch (const boost::filesystem::filesystem_error& ex)
{
std::cout << "Failed to copy files. " << strerror(errno) << std::endl;
}
In one scenario the hard disk was full which caused the file copy to fail and strerror() returned "No Error". The exception object provided a correct "There is not enough space on the disk" error.
Before making any changes to the code I wanted to understand strerror.
- Is it "only" C runtime libraries that register errors "in" strerror?
- Are there any scenarios where strerror will provide a better error message than for example a filesystem exception?
- If we are not calling any C runtime functions directly, do we have any reason to use strerror()?
Using boost 1.71 on Windows and Linux
Appreciate any input
copy_filehas two overloads:This applies both to the boost and standard library implementations. In the snippet you provide, no
error_codeinformation is passed to the call so all error reporting should be done using the exception object.That said, to address specific questions:
No. Case in point, for the standard library version:
"The overload taking a std::error_code& parameter sets it to the OS API error code if an OS API call fails, and executes ec.clear() if no errors occur."
Hardly, because the exception message is essentially a concatenation of "
fromas the first path argument,toas the second path argument, and the OS error code as the error code argument".It's not about "message richness". There are some implications with thread safety (read up on the provided links) but the non throwing versions are to be used where exceptions are not a fitting choice e.g.: