Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

32 linesCodeBlameRaw
1# apps/web
2
3## A part that fails stays in its part
4
5Every page is built so one failed read or one broken card never takes the
6page down. Follow this on any page you add or change; older pages are
7brought up to it as they are worked on.
8
9- **What a page is about is read strictly.** The pull request on its page,
10 the settings being edited, anything that decides access or a redirect:
11 if that fails, the page fails, inside its frame (routes/page-boundary.tsx).
12- **Everything beside it is a part.** Read it through
13 `part(promise, "What it is")` (app/lib/partial.ts). It gives the value, or
14 `Failed` when the service did not answer or answered with a 5xx. A 404 or
15 a refusal (`{ ok: false }`) is an answer, not a failure: read it as before.
16- **A failed part says so in its own place**, the way a form says what is
17 wrong beside the field: `<Unavailable what="…" />`
18 (app/components/boundary.tsx; `compact` in a sidebar or small slot),
19 under the card's heading. Never let a failure read as an empty or false
20 state ("No deployments yet", "Checks are off").
21- **A form whose data failed is not shown.** Show Unavailable instead, so
22 nothing is saved over values that were never read.
23- **Quiet fallback only for what nobody would miss** (a decoration, a
24 suggestion the server checks again): `orElse(await part(…), fallback)`,
25 with a comment saying why.
26- **A complex card sits in `<Boundary what="…">`**, so an error while
27 drawing stays in the card. `Panel` does this already.
28- **A streamed promise never rejects into an `<Await>` without an
29 `errorElement`**: resolve it through `part`, or give it one.
30
31Network blips are handled once for every page (app/lib/resilient-fetch.ts,
32components/connection-toast.tsx); the root error page is the last resort.