Boost::file_system: Checking error codes
boost, boost-filesystem, c++, system-error
Solution
`error_codes` and `error_conditions` with different `error_categories` are allowed to have the same `value()`. The non-member comparison functions check both the the value and category:
`bool operator==( const error_code & lhs, const error_code & rhs ) noexcept;`
Returns: `lhs.category() == rhs.category() && lhs.value() == rhs.value()`.
Hence, the exceptions's `error_code` could be checked against the return from `make_error_code()`, such as follows:
try {
// If p2 doesn't exists, canonical throws an exception
// of No_such_file_or_directory
path p = canonical(p2);
// ...
} catch (filesystem_error& e) {
if (e.code() ==
make_error_code(boost::system::errc::no_such_file_or_directory)) {
custom_message(e);
}
}
Here is a complete example demonstrating two `error_code`s that are not equivalent despite having the same value:
#include <boost/asio/error.hpp>
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
int main()
{
// Two different error codes.
boost::system::error_code code1 = make_error_code(
boost::system::errc::no_such_file_or_directory);
boost::system::error_code code2 = make_error_code(
boost::asio::error::host_not_found_try_again);
// That have different error categories.
assert(code1.category() != code2.category());
assert(code1.default_error_condition().category() !=
code2.default_error_condition().category());
// Yet have the same value.
assert(code1.value() == code2.value());
assert(code1.default_error_condition().value() ==
code2.default_error_condition().value());
// Use the comparision operation to check both value
// and category.
assert(code1 != code2);
assert(code1.default_error_condition() !=
code2.default_error_condition());
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Test with Boost.Filesytem
try
{
boost::filesystem::canonical("bogus_file");
}
catch(boost::filesystem::filesystem_error& error)
{
if (error.code() ==
make_error_code(boost::system::errc::no_such_file_or_directory))
{
std::cout << "No file or directory" << std::endl;
}
if (error.code() ==
make_error_code(boost::asio::error::host_not_found_try_again))
{
std::cout << "Host not found" << std::endl;
}
}
}
Which produces the following output:
No file or directory
Problem
Although I'm using C++11, this question is boost-related, since I'm processing errors from `boost::file_system`. In the following situation: ``` try { // If p2 doesn't exists, canonical throws an exception // of No_such_file_or_directory path p = canonical(p2); // Other code } catch (filesystem_error& e) { if (e is the no_such_file_or_directory exception) custom_message(e); } // other catchs } ``` If I print the error value when the desired exception (no_such_file_or_directory) is thrown: ``` // ... } catch (filesystem_error& e) { cout << "Value: " << e.code().value() << endl; } ``` I get the value `2`. It is the same value of `e.code().default_error_condition().value()`. My questions is: could different error conditions from different error categories have same values? I mean, does I need to check both, error categories and error values, in order to ensure I'm getting a specific error? In such a case, what is the cleanest way to do it?