In writing a function to convert between strings of different encodings (e.g. from UTF-8 to UTF-16), what would be the best way to handle errors (e.g. invalid input UTF-8 byte sequence)? Throwing an exception or returning an error code (even a bool
)?
// Throws a C++ exception on error.
std::wstring ConvertFromUtf8ToUtf16(const std::string& utf8);
// Returns true on success, false on error.
bool ConvertFromUtf8ToUtf16(std::wstring& utf16, const std::string& utf8);
Using exceptions, it would be possible to do chained function calls (when the function return value is used as input for other functions/methods).
But I'm not sure that using exceptions in this case is good; I was thinking of what Eric Lippert in his quality blog post calls vexing exceptions (and related Int32.Parse()/TryParse()
example).
For example, if exceptions are used, the caller should be forced to wrap the function call in try/catch
blocks to check the case of invalid UTF-8 input:
try
{
wstring utf16 = ConvertFromUtf8ToUtf16(utf8);
}
catch(const Utf8ConversionException& e)
{
// Bad UTF-8 byte sequence
...
}
Which seems not ideal to me.
Maybe the best thing to do is to just provide both overloads (implementing the conversion code in the non-throwing overload, and in the throwing overload just call the non-throwing version, and in case of error return code throw an exception)?