Error handling

Design7 standards

Exceptions, expected/optional, noexcept, contracts.

Drill points
  • Basic vs strong vs nothrow guarantees
  • noexcept as contract vs as optimization
  • Composing expected pipelines
  • Designing an error taxonomy (error_code vs enums vs types)

Exceptions plus the guarantee vocabulary (basic/strong/nothrow); noexcept enters the type of the contract; std::error_code/system_error give non-throwing channels for expected failures.

void push(T v);                  // basic guarantee
void swap(Vec& o) noexcept;      // nothrow — enables strong patterns
std::error_code last_error() const noexcept;

No change — the exceptions-vs-codes split by failure kind (exceptional vs expected) is the working rule.

std::optional becomes the idiomatic “no value, no explanation needed” return; [[nodiscard]] stops silently ignored results.

[[nodiscard]] std::optional<User> find_user(Id id);
if (auto u = find_user(id)) greet(*u);

std::source_location enriches diagnostics without macros; concepts produce readable errors at API boundaries instead of instantiation stacks.

void log_error(std::string_view what,
               std::source_location where = std::source_location::current());

std::expected<T, E> is the missing sum type for fallible operations, with monadic and_then/transform/or_else on both expected and optional for pipeline composition.

std::expected<Config, ParseError> parse(std::string_view src);

auto port = parse(src)
    .transform([](const Config& c) { return c.port; })
    .value_or(8080);

Contracts split bugs from recoverable errors: pre/post/contract_assert state what must hold, with ignore/observe/enforce semantics — assertions become a language feature with a violation handler, not a macro.

double safe_div(double a, double b)
  pre(b != 0.0)
{ contract_assert(std::isfinite(a)); return a / b; }
C++29direction · not adopted

Direction: contracts on virtual functions and further semantics, plus pattern matching over expected/variant as the consumption syntax for value-based errors.

C++26 per the final working draft; C++29 rows are proposals and direction, not adopted features.