Good Code
The good version catches a domain exception and translates it into an expected error string. The caller still receives the failure reason.
Lesson 06
Catch exceptions at boundaries where code can translate them into a result the caller understands.
#include <expected>
#include <string>
std::expected<Review, std::string> load_review_result(const std::string& path)
{
try {
return parse_review_file(path);
} catch (const ParseError& error) {
// Boundary translation preserves the parser failure message.
return std::unexpected(error.what());
}
}#include <optional>
#include <string>
std::optional<Review> load_review_result(const std::string& path)
{
try {
return parse_review_file(path);
} catch (...) {
// Catching every exception erases the original failure.
return std::nullopt;
}
}The good version catches a domain exception and translates it into an expected error string. The caller still receives the failure reason.
The bad version catches every exception and returns an empty optional. It hides parse errors, file errors, and programming errors behind the same result.