Learn / Errors and failures
The mental model
a failure the reader can act on
└─▶ a typed value ──Message──▶ update ──▶ Model ──▶ view draws it ──▶ the reader acts ──▶ Message
a failure only a developer can fix
└─▶ a Diagnostic ──Diagnostics.report──▶ Diagnostics.Reporter ──▶ Effect's log, or your sinkThree rules follow from it.
- A value once shown stays on screen. A refresh that fails keeps the value
it was refreshing; a list keeps the rows it can draw. A reader keeps working
with what they had, told that it may be stale. One case breaks it: a field
that only a write's optimistic layer showed, and that its answer left out,
reads
Loadinguntil it is fetched again. The answer carries what the Surfaces show of every row it names, so this is a row the server did not name, or an answer whose read failed (AnswerUnread);verifyPredictionsreports such a field as aPredictionMismatch'sGap(see Checking an answer against what was shown). - Nothing a reader started is retried on its own. A failed read waits for
Data.refresh, and a failed write forData.retry. A persistent error asked again on every unrelated change would hammer the server and hide the failure. Only the transports retry by themselves (a live stream, a Sync exchange, the durable outbox sending a write nothing answered), since asking again changes nothing the reader sees. - A diagnostic never changes behaviour. A read, a write and a placement behave the same whether one is reported or not. The channel says why; it decides nothing.