epitaph

Synopsis

Declared in <folly/result/epitaph.h>

template<typename... Args>
error_or_stopped
epitaph(
    error_or_stopped eos,
    ext::format_string_and_location<Args...> snl = "",
    Args const&... args);

Description

You can add epitaphs to errors in result & error_or_stopped with allocation‐free literals, or via fmt::format), and source locations:

r = epitaph(my_result()) // only the source location r = epitaph(my_result(), "ctx") // location & string literal r = epitaph(my_result(), "fmt {}", a) // formatted, on heap

This takes ownership of the 1st argument, and returns a same‐type value.

Thread‐safety: The underlying exception MAY BE MUTATED, if it derives from rich_error_base. Do NOT allow concurrent access to exception objects!

If the input is in a value state, it is not changed. Non‐value states (both error & stopped) are annotated with epitaphs (current location & message).

Crucially, epitaph never changes the type nor the get_rich_error_code()`s of the error ‐‐ access to both will work the same as before adding epitaphs. So, this works, as do `has_stopped() checks:

eos = epitaph(error_or_stopped{std::logic_error{"BUG"}}, "AT"); if (auto ex = get_exception<std::logic_error>()) { // NOT auto*! LOG(INFO) << ex; // Prints: AT @ src.cpp:42 ‐> BUG }

For a wrapper that can change codes, check out nestable_coded_rich_error.

How epitaphs work under the hood:

  • The inner logic_error is wrapped with a rich_error , but this is not observable via APIs besides get_outer_exception(). Seek result maintainer advice before using this function!

  • For normal error access, our get_exception implementation returns a special rich_ptr_to_underlying_error that quacks like a pointer to the underlying error, but prints the epitaph stack when formatted.

On the "value" path, the perf cost is minimal ‐‐ 1 branch. On the "error" path, adding epitaphs may allocate a new std::exception_ptr (now 60ns for ctor + dtor, could use some micro‐optimization), but given demand we can amortize this to 5ns per call.

Epitaphs work regardless of the underlying exception type. Epitaph data are exposed in an RTTI‐free way via rich_error_base, so non‐rich errors are necessarily wrapped.

Future: epitaphs.md has pointers on how the epitaphs support should evolve (for better perf & usability).

Does not throw when no format args are used (literal or empty message). Else, fmt may throw bad_alloc ‐‐ but not make_exception_ptr_with.

Return Value

The annotated error‐or‐stopped state.

Parameters

Name

Description

eos

The error‐or‐stopped state to annotate.

snl

The format string and captured source location.

args

Format arguments for the annotation message.

Created with MrDocs