fix(frontend): contain viewer/widget crashes with error boundaries
A render error in one viewer or gate widget unmounted the whole React root (white screen). Add a reusable ErrorBoundary (class component, no new dep) with resetKeys + an on-brand fallback, and wire it at two surfaces: - WidgetHost: isolates the gate widget (reset on descriptor id) so a malformed gate payload no longer blanks the conversation - SessionDocumentsPanel: wraps each document (reset on doc key/content) so one crashing viewer degrades only its section; siblings and the panel survive The observed crash: a schema-linking doc that parses but lacks `candidates` makes SchemaLinkingViewer throw. Verified live via Playwright against the mock backend. TDD throughout; tsc clean, 123/123 vitest (+8 new tests). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { useSessionStore } from "../store/sessionStore";
|
||||
import { resolve } from "../widgets";
|
||||
import { postResponse } from "../api/sessions";
|
||||
import type { UiResponse } from "../api/types";
|
||||
import { ErrorBoundary } from "../components/ErrorBoundary";
|
||||
|
||||
export function WidgetHost({ sessionId }: { sessionId: string | null }) {
|
||||
const pending = useSessionStore((s) => s.pendingWidget);
|
||||
@@ -32,5 +33,11 @@ export function WidgetHost({ sessionId }: { sessionId: string | null }) {
|
||||
});
|
||||
clearPending();
|
||||
};
|
||||
return <Renderer descriptor={pending} onRespond={onRespond} />;
|
||||
// A malformed gate payload must not white-screen the whole app: isolate the
|
||||
// widget render. resetKeys on the descriptor id so the next gate starts clean.
|
||||
return (
|
||||
<ErrorBoundary resetKeys={[pending.id]} label="step">
|
||||
<Renderer descriptor={pending} onRespond={onRespond} />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user