I'd like to have a custom exception that has embedded contextual information, including strings, and a formatted what()
.
e.g.:
struct MyError : public std::runtime_error {
MyError(std::size_t line, std::size_t column, std::string expected, std::string found)
: std::runtime_error(FormatPrettyMessage(...)), line(line), column(column), expected(expected), found(found) {}
MyError(const MyError&) = default;
MyError& operator =(const MyError&) = default;
~MyError() = default;
size_t line;
size_t column;
std::string expected; // these are
std::string found; // problematic
};
Best practices, though, say an exception should have a noexcept
copy constructor, because throwing might involve implicit copying.
The above can't have a noexcept
copy constructor, as copying a string can throw std::badalloc
. cppreference hints that standard libraries use a copy-on-write string to avoid this (libstdc++ indeed uses an internal COW string implementation).
But how should a layperson idiomatically add a string member to their custom exception? Trying to serialize my data and stuff it into the runtime_error
message, as this answer recommends, feels hacky and forces the exception handling code to parse and reformat the what()
output. But throwing a whole custom string into my small project just to make an exception pretty feels excessive.