The system specific error codes used by the filesystem library can be found in the __std_win_error
enum. Note how the numerical values map 1:1 to the values returned by the Win32 API function GetLastError
:
enum class __std_win_error : unsigned long {
_Success = 0, // #define ERROR_SUCCESS 0L
_Invalid_function = 1, // #define ERROR_INVALID_FUNCTION 1L
_File_not_found = 2, // #define ERROR_FILE_NOT_FOUND 2L
_Path_not_found = 3, // #define ERROR_PATH_NOT_FOUND 3L
_Access_denied = 5, // #define ERROR_ACCESS_DENIED 5L
_Not_enough_memory = 8, // #define ERROR_NOT_ENOUGH_MEMORY 8L
_No_more_files = 18, // #define ERROR_NO_MORE_FILES 18L
_Sharing_violation = 32, // #define ERROR_SHARING_VIOLATION 32L
_Not_supported = 50, // #define ERROR_NOT_SUPPORTED 50L
_File_exists = 80, // #define ERROR_FILE_EXISTS 80L
_Invalid_parameter = 87, // #define ERROR_INVALID_PARAMETER 87L
_Insufficient_buffer = 122, // #define ERROR_INSUFFICIENT_BUFFER 122L
_Invalid_name = 123, // #define ERROR_INVALID_NAME 123L
_Directory_not_empty = 145, // #define ERROR_DIR_NOT_EMPTY 145L
_Already_exists = 183, // #define ERROR_ALREADY_EXISTS 183L
_Filename_exceeds_range = 206, // #define ERROR_FILENAME_EXCED_RANGE 206L
_Directory_name_is_invalid = 267, // #define ERROR_DIRECTORY 267L
_Max = ~0UL // sentinel not used by Win32
};
However, you should not ever test against these directly. The whole point of the system_error
design is to not have to interpret system specific error_code
s directly, but instead only interpret them via their associated error_category
.
In particular, the category maps error_code
values to error_condition
s. The implementation throws an error_code
, but the client application should always check for error_condition
s. Unlike error_code
, error_condition
s are portable and do not rely on implementation details.
So here's how you should treat those kinds of errors in code: Check the std::errc
for values that you would like to handle programmatically. Then check the error_code
against those values:
std::error_code ec;
std::filesystem::copy("source.txt", "destination.txt", ec);
if (ec) {
if (ec == std::errc::file_exists) {
// special error handling for file_exists
// [...]
} else {
// generic error handling for all other errors
// that you don't specifically care about
std::cerr << "Error: " << ec.message() << "\n";
}
}
There will likely be some errors left over, but since you almost certainly will not be able to come up with a specialized error handler for those anyway, just put in a catch-all generic error handler for all the error conditions that you don't care about.
Chris Kohlhoff, one of the original authors of the system error library has a great, if somewhat dated, blog series explaining the design and intended use of the error handling mechanism.
GetLastError
. As the C++ Runtime Library implementation must eventually call through to the WinAPI level I don't think it's possible to get a complete list of errors. As an example see the docs forCreateFileW
learn.microsoft.com/en-gb/windows/win32/api/fileapi/… "...If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError...." – Veneauxstd::error_code
's design is that you can still perform reasonable error handling even if you don't know anything about the individual error values. – Paisa