diff --git a/src/components/ui/SectionErrorBoundary.tsx b/src/components/ui/SectionErrorBoundary.tsx index 88d7f84..e69de29 100644 --- a/src/components/ui/SectionErrorBoundary.tsx +++ b/src/components/ui/SectionErrorBoundary.tsx @@ -1,90 +0,0 @@ -import { Component, type ErrorInfo, type ReactNode } from "react"; - -/** - * Per-section error boundary inserted around every assembled section by the - * backend's page-assembler. Goal: a single section that throws at runtime - * (missing required prop, broken `.map`, etc.) shows a small placeholder - * instead of taking down the entire page with a white screen. - * - * Also reports the failure via the `/__webild/render-status` probe channel - * so Bob-AI's post-commit poll picks up the section name + error message and - * the model gets the signal to fix the right section on the next loop turn. - * - * The probe POST is best-effort and silent — sandbox-only (gated by - * `window.parent !== window`), so production deploys never call it. - */ - -interface Props { - /** Section slug — same value the wrapping `
` uses. */ - name: string; - children: ReactNode; -} - -interface State { - hasError: boolean; - errorMessage?: string; -} - -const RENDER_STATUS_URL = "/__webild/render-status"; - -export default class SectionErrorBoundary extends Component { - state: State = { hasError: false }; - - static getDerivedStateFromError(error: unknown): State { - return { - hasError: true, - errorMessage: - error instanceof Error ? error.message : String(error ?? "unknown"), - }; - } - - componentDidCatch(error: Error, info: ErrorInfo) { - if (typeof window === "undefined") return; - if (window.parent === window) return; - try { - fetch(RENDER_STATUS_URL, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - ok: false, - reason: "section_error_boundary", - section: this.props.name, - error: String(error?.message || error || "unknown"), - stack: String(error?.stack || "").slice(0, 4000), - componentStack: String(info?.componentStack || "").slice(0, 4000), - t: Date.now(), - }), - keepalive: true, - }).catch(() => {}); - } catch { - /* ignore */ - } - } - - render() { - if (this.state.hasError) { - return ( -
-

- This section failed to render. -

-

- Section: {this.props.name} -

- {this.state.errorMessage ? ( -

- {this.state.errorMessage} -

- ) : null} -

- Tell Bob exactly what's wrong (e.g. "fix the {this.props.name} section") to retry. -

-
- ); - } - return this.props.children; - } -}