Report crash: does Retry ever work?
The pane: first crash and repeat crash
This report couldn’t be shown.
This report couldn’t be shown.
This report couldn’t be shown.
docs/mockups/n08-button-set.html). Frame 1 ships today and is unchanged. Frames 2: once the reload that Retry asked for crashes too, Retry gives way to one secondary Send feedback with no default button, so Return does nothing, the same as N08 after its failed retry. The sentence stays. Both labels are existing strings: desktop.menu.help.sendFeedback on the Mac and footer.giveFeedback in a browser. On the Mac it opens this window’s native FeedbackSheet in N08’s problem mode (via project-action: open-feedback), because the web modal lives inside the crashed layout. In a browser, the fallback mounts the web FeedbackModal in the same mode.
The sheet it opens
How is Bristlenose working for you?
Bristlenose had a problem
FeedbackModal, and the Mac’s native FeedbackSheet matches it. Green is N08’s problem wording (two keys × 21, added by the N08 build and reused here, never a parallel pair; strings from n08-problem-report.html). The send carries "kind": "problem", so the subject reads “Bristlenose problem report”. The website’s feedback.php deploys before any app that sends it. The prefill is existing strings only: labels.reportError, then the error line (name and message plus the route, what the popover caption already shows), visible and editable, so the anonymity line stays true. It carries no project name, path or stack frames, and no new key. The rating is still required, as in N08.
Can a reload fix it? What reaches this pane
| Cause | Reaches the whole-report pane? | Does Retry (a reload) fix it? |
|---|---|---|
A throw in a modal’s own body (hooks, values above return) | Yes (frontend/CLAUDE.md, R85) | Yes: the reload closes the modal. Opening it again crashes again. |
A lazy chunk that won’t load: Settings, Miro, FigJam (AppLayout.tsx:997–1010, a Suspense with no boundary) | Yes | Yes: index.html is no-cache (app.py:489), so a reload fetches the new hashes. Cases: a CLI upgrade under a running serve, or a blip. On the Mac the bundle can’t change under a running app. |
| A timing race (async answers arriving in an unexpected order) | Yes | Usually: nothing is persisted. |
| A throw in AppLayout or unbounded chrome from the study’s data | Yes | No: the same data comes back, every reload, until a run or an edit changes it. |
| A throw from saved per-viewer state: localStorage, report prefs seeded by the shell (R89), sessionStorage (it survives a reload) | Yes | No: the state is re-read on every reload. |
| A failed data read (fetch error, 404, 401) | No: stores catch it, and lenses render ErrorNotice scope="lens" (R86) | n/a |
| Serve restart or serve down | No: on the Mac a new port changes the URL and the shell reloads the web view itself (WebView.updateNSView), and a dead serve shows the boot pane (N08). In a CLI browser the reload gets the browser’s own error page. | n/a |
| Web content process killed (memory) | No: a different WebKit path, not a React throw | n/a |
Conclusion: Retry has real wins (the first three rows), so it stays on the first crash. A crash that survives one Retry is almost always one of the two “No” rows, and a second Retry would fail the same way. Nothing counts repeats today: the SPA posts each crash, BridgeHandler.reportCrash is one optional that the next crash replaces, and RouteError keeps no state. Retry is window.location.reload(), so the mark has to survive a reload. On the Mac the shell can tell, since “a report-error with no route-change since the last one” is the same as N08’s startedByRetry. A CLI browser has no shell, so it needs a one-key sessionStorage mark set by Retry and cleared on a good mount. That one mark serves both, and the plan picks the mechanism.