Using std::error_code with non-integer values
c++, c++11, error-code
Solution
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.");
Problem
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`?