Redefining message()
You may remember that our custom _file_io_error_domain
inherits from
outcome_e::posix_code::domain_type
, and thus does not have to
implement the many pure virtual functions required by outcome_e::status_code_domain
.
What we do need to do is reimplement _do_message()
to append the
file and line information to the POSIX error description string
returned by outcome_e::posix_code::domain_type
. This causes
the status code’s .message()
observer to return a string
with the extra payload information represented in text.
// Return a string describing a specific code. We will return the
// string returned by our POSIX code base domain, with the source
// file and line number appended
virtual _base::string_ref _do_message(const outcome_e::status_code<void> &code) const noexcept override final // NOLINT
{
assert(code.domain() == *this);
// Fetch message from base domain (POSIX)
auto msg = _base::_do_message(code);
const auto &c1 = static_cast<const file_io_error &>(code); // NOLINT
const value_type &v = c1.value();
// Append my source file and line number
if(v.file == nullptr)
{
return msg;
}
size_t length = strlen(v.file) + 16 + msg.size();
auto *p = static_cast<char *>(malloc(length)); // NOLINT
if(p == nullptr)
{
return _base::string_ref("failed to get message from system");
}
sprintf(p, "%s (%s:%d)", msg.data(), v.file, v.lineno);
// Return as atomically reference counted string
return _base::atomic_refcounted_string_ref(p, length);
}
};