ADR-240: An Error Keeps Its Site When It Hops Into the Box

Status: Superseded by ADR-280 — its D1-D2 are D28-D29 there, D3 is in D20 Date: September 27, 2026 Target Version: Nikaia 0.0.226 Answers: #199, what the box still costs — an error a callee raised in a typed channel lost its site when a ? put it in the box Refines: ADR-157 D2 (the typed envelope, Thrown<E>), ADR-170 D1 (the list every error carries) Related: ADR-023 D6 (an error knows where it was raised), ADR-159 D3 (what the long form says where there is no site), ADR-239 D3 (a cleanup’s failure joins the error already leaving)

1. Context

A function’s failure channel is typed where the compiler can name what it throws — Thrown<E>, an envelope holding the error, the site of its throw and the list of failures that joined it — and the box, Box<dyn Error>, where it cannot. A ? from a typed callee into a boxed caller converted through the language below’s own From<E: Error> for Box<dyn Error>, because Thrown<E> was an Error. The envelope went into the box whole, as an opaque value, and nothing there could reach its site or its list without knowing E: error.full() said raised below Nikaia; no site recorded about an error the program itself had thrown, and a failure that joined it later — a cleanup’s, an overlap branch’s — was dropped.

2. Decisions

D1 — A Thrown<E> put in the box becomes the box’s own envelope, with its site and its list.

std writes From<Thrown<E>> for Box<dyn Error>, which makes a Raised of it: the same error, the same site and trace, and every failure on its list converted the same way. Thrown<E> is therefore not an Error itself — were it one, the blanket conversion would still be the one a ? takes, and the two would overlap. Nothing is lost by it: a typed channel is never a dyn Error anywhere but on this hop, and this hop is now the envelope’s.

An error that reaches the box with no envelope at all — a library’s — is put in one when something joins it, with no site, so what joins it is kept.

The emitter writes nothing new: the ? is the one it wrote, and the conversion it takes is std’s.

D2 — A cleanup’s failure is raised where the settle point is.

The settle points of ADR-239 hand a failing cleanup on as a Thrown<Failure> raised at the function the settle point stands in, so the long form says raised at both under cleaning up a Flaky failed rather than no site recorded.

D3 — The note about a missing trace is said once.

The long form of a boxed error said (no trace; set NIKAIA_TRACE=1 to capture one) under every failure that joined it; the typed envelope said it once, at the top. Both say it once.

3. Rejected alternatives

This site is open source. Improve this page.