问题
I'm writing a library and want to return error codes whenever an error is returned by a remote system. The problem is that these are identified by strings, eg, "0A01" and also contain a message, and error code requires an integer as value.
What is the best way to implement an error code, with all the functionality that std::error_code
provides but that uses strings as the value? How do I add an external error string to the std::error_code
or std::error_category
?
回答1:
As mentioned in the comments, you must know the error codes, which could be received from the remote server.
The std::string
which you receive from a remote server contains 2 parts as you said,
The problem is that these are identified by strings, eg, "0A01" and also contain a message, and error code requires an integer as value.
As you haven't shared the format of the error message, I am not adding the code for spiting it, split your string into 2 parts,
- Error Code
- Error Message
Now you can convert Error Code of type std::string
to int
by using std::stoi(error_code)
, So lets say
int error_code_int = std::stoi(string_to_hexadecimal(error_code));
And for std::error_category which serves as base class for our custom error messages, do this,
std::string message_received = "This is the message which received from remote server.";
struct OurCustomErrCategory : std::error_category
{
const char* name() const noexcept override;
std::string message(int ev) const override;
};
const char* OurCustomErrCategory::name() const noexcept
{
return "Error Category Name";
}
std::string OurCustomErrCategory::message(int error_code_int) const
{
switch (error_code_int)
{
case 1:
return message_received;
default:
return "(unrecognized error)";
}
}
const OurCustomErrCategory ourCustomErrCategoryObject;
std::error_code make_error_code(int e)
{
return {e, ourCustomErrCategoryObject};
}
int main()
{
int error_code_int = std::stoi(string_to_hexadecimal(error_code)); // error_code = 0A01
ourCustomErrCategoryObject.message(error_code_int);
std::error_code ec(error_code_int , ourCustomErrCategoryObject);
assert(ec);
std::cout << ec << std::endl;
std::cout << ec.message() << std::endl;
}
The output for above working example is
Error Category Name : 0A01
This is the message which received from remote server.
You can use function string_to_hexadecimal()
from this post.
I hope that now you can modify the above code according to your needs.
Edit 1:
As you said that:
This assumes the dynamic message is a global value. How do I pass it to an
std::error_category
object?
You can see that both std::error_code::assign and constructor std::error_code::error_code are taking parameters of int
for error code number and error_category
. So It is obvious that std::error_code
can't take the dynamic message.
But wait, I said std::error_code
are taking error_category
as an argument in constructor, so is there any way, we can assign the dynamic message there ?
std::error_category states that:
std::error_category
serves as the base class for specific error category types.
So it means that the struct
we derived from std::error_category
at the following line
struct OurCustomErrCategory : std::error_category
can have a data member and we can assign it via member function, so our struct
will become like that,
struct OurCustomErrCategory : std::error_category
{
std::string message_received;
OurCustomErrCategory(std::string m) : message_received(m) {}
const char* name() const noexcept override;
std::string message(int ev) const override;
};
and you can assign it like that wherever you want,
const OurCustomErrCategory ourCustomErrCategoryObject("This is the message which received from remote server.");
回答2:
Don't subclass error_code. You need to write your own error category, which maps integers to your specific errors. This is a step-by-step description on how to do it:
http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-4.html
来源:https://stackoverflow.com/questions/43856612/using-stderror-code-with-non-integer-values