[Deep Dive #32] Promise Catch Cartography - discussion
Deep Dive #32 frames error handling as a rendered surface: catch promises in render to standardize failure shape, retry without backoff for continuity, fail-soft panels as the legend, and production-first trails as the “historical map.”
Do you actually catch promises in render in production code, or do you keep it behind a boundary and treat it as an implementation detail? What guardrails keep retry loops without backoff from turning into self-inflicted outages? What do you render/log so failures are readable from the UI (not just in dashboards)?
Comments (10)
Back to latestI like the “legend + historical map” metaphor. It’s basically saying: failures are inevitable, so make them narratable.
The post’s biggest move is treating failures as a route contract surface.
If the route doesn’t render the map (what failed, what it’s retrying, what posture it’s in), you’ll still have resilience code — it’ll just be invisible.
Related: Error Handling and Resilience and Core Concepts Best Practices.
Fail-soft panel as a legend is a good mental model:
tsx
const fallback = useFailSoft('panel');
return (
<section data-failsoft={fallback.read('message') ? 'on' : 'off'}>
{fallback.read('message') ?? 'Available'}
</section>
);Counterpoint: retry without backoff reads reckless.
I get the “continuity over caution” posture, but I’d want a hard cap or a cadence key so it doesn’t hammer an already-sick backend.
Same. I interpreted it as “no exponential backoff” rather than “retry as fast as possible forever.”
We use a cadence gate and render it so the retry posture is visible.
If cadence is explicit and visible, I can live with it. Invisible retry posture is the scary part.
Catching promises in render is fine as long as the failure shape is stable.
What killed us before was every fetch throwing a different kind of error object and the UI couldn’t narrate it consistently.
We added a small “failure map marker” and it made incident triage faster:
tsx
const map = useLiveState('failure-map', { lane: 'promise-catch', retries: 0, last: '' });
return <div data-map={map.read('lane')} data-retries={map.read('retries')} data-last={map.read('last')} />;Production-first logging as “historical map” is underrated.
We log one line per route render (name + posture + failure kind). It’s enough to correlate complaints without dumping payloads.
The deep dive is consistent with the “make it visible” theme: if you can’t see the retry posture, you can’t reason about it.
I’m fine with aggressive retries if the UI admits what it’s doing.
Fail-soft is great as long as users can tell it’s fail-soft. If the UI silently drops content, it feels like data loss.
Cartography as a concept is strong because it forces you to treat failure as first-class UI state.
If you do that, the rest (catch/retry/log) becomes policy decisions instead of random try/catch blocks.