Error handling¶
- A fallible operation returns
std::expected<T, E>. Chain results withand_then,or_else,transformandtransform_errorrather than nestingifs. - Each module has its own error type, added as the need arises:
core::net::NetError(withNetErrorCode),core::platform::PlatformError. - The one exception type is
core::async::OperationCancelled. A coroutine throws it when its own stop token cancels it, so cancellation unwinds a whole chain of coroutines at once. - A cancellation that comes from the resource is a value. Closing a socket, calling
cancelRead()or closing a listener completes a pending operation withNetErrorCode::Cancelled, not an exception. - If data already arrived, the data wins over a concurrent cancellation.
- A precondition violation is an assertion, not an error code: there is no result it could return that would be true, so an error code would make every caller handle a case that cannot legitimately happen.
- The reason is captured where it happens. An
errno, anerror_codeor a Windows error is available only at the point of failure; aboolresult loses it.
The design is Part I ยง2 of the
design spec;
the rules are in
design-principles.md.