Lately I've been converting some libraries to use the <system_error>
facilities in C++11.
I'm having difficulty understanding the use cases for std::error_code
vs. std::error_condition
.
Note, I understand the difference - there are many questions on stackoverflow which go over the difference.
The basic difference is that std::error_code
is supposed to represent a system- or platform-specific error, whereas std::error_condition
is an abstract error that an API or user interface should return.
Okay - but I'm having trouble understanding why we would ever use std::error_code
in practice. It seems to me you're either going to :
Be dealing with a system specific error reporting mechanism (like
say, errno
or something returned from a POSIX call, or say, a call
to getsockopt
with SO_ERROR
on Linux) which you can easily
convert to an std::error_condition
via the std::errc
enums, which are supposed to be portable.
Be using a user-defined category of errors, which represent application-level
or business-logic errors, like "invalid social security number" or
whatever - which also would be a use case for
std::error_condition
.
Be dealing with some low-level interface or library which defines its own error reporting mechanism, such as OpenSSL, in which case you would be directly using platform-specific error mechanisms. In this case you'd then need to convert or map these errors to an std::error_code
. But if you're going to go through the trouble of converting these platform specific errors to something generic like std::error_code
, why not just convert to std::error_condition
?
Also, since POSIX system errors are supposed to be portable, and since they map one-to-one with std::error_condition
via the std::errc
enum, I can't find any use case for std::error_code
. Most Linux/UNIX system calls set errno
, which is supposed to portably map to std::error_condition
.
So, I don't see any use case for std::error_code
anywhere. So, what are some example use cases where we would want to use std::error_code
instead of std::error_condition
?
I was wondering about that a while back myself and found the answer here. Essentially, error_code
is used to store and transport error codes, while error_condition
is used to match error codes.
void handle_error(error_code code) {
if (code == error_condition1) do_something();
else if(code == error_condition2) do_something_else();
else do_yet_another_thing();
}
Each error_condition
is equivalent to a set of error_code
, possibly from different error_categories
. This way you can treat all errors of a certain type the same, no matter which subsystem they originate from.
error_code
on the other hand contains exactly the category of the subsystem it originated from. This is useful for debugging and when reporting the error: you may be interested to know whether a "permission denied" error was because of insufficient access rights on the local file system or because of a 403 error that your http-downloader-library received, and may want to put that detail in the error message, but your program has to abort either way.
What constitutes equivalence is defined by the categories; if the error_code
's category considers the error_condition
equivalent, or the error_condition
's category considers the error_code
equivalent, then operator==
returns true
for that pair of error_condition
and error_code
. That way you can have error_code
s from your own error category and make them equivalent to certain generic or system error_condition
s.