# Mode Error Boundary

Mode Error Boundary [#mode-error-boundary]

The **Mode Error Boundary** is a React error boundary that isolates a render
failure in its subtree. When a child throws during render, it catches the error
and renders a compact recoverable `role="alert"` notice with the message and a
**Reset** button that clears the error and re-renders the children — so a single
failing surface (one tab, one result panel) cannot blank the whole page.

> **Structural utility.** It is a copy-owned class error boundary with local prop
> shapes — no backend, no model, no `@localmode/*` dependency. Wrap any subtree
> whose render could throw.

**When to use it:** around each independently-rendered result surface (a tab, a
mode, a widget) so an error in one is contained and recoverable in place.

Preview [#preview]

```tsx
'use client';

import { useState } from 'react';

import { ModeErrorBoundary } from '@/components/mode-error-boundary';

/** A child that throws during render when `shouldThrow` is true. */
function ResultSurface({ shouldThrow }: { shouldThrow: boolean }) {
  if (shouldThrow) throw new Error('Simulated render failure in the result surface.');
  return <p className="text-sm text-muted-foreground">Result rendered successfully.</p>;
}

/**
 * Demo for ModeErrorBoundary, used by the docs live preview. "Break" makes the
 * child throw so the boundary shows its recoverable notice; "Fix" clears the
 * underlying condition, then the notice's Reset button re-renders the child.
 */
export default function ModeErrorBoundaryDemo() {
  const [shouldThrow, setShouldThrow] = useState(false);

  return (
    <div className="flex w-full max-w-md flex-col items-start gap-3">
      <div className="flex items-center gap-2 text-xs">
        <button
          type="button"
          onClick={() => setShouldThrow(true)}
          className="rounded-md border border-border px-3 py-1.5 font-medium hover:bg-muted"
        >
          Break the surface
        </button>
        <button
          type="button"
          onClick={() => setShouldThrow(false)}
          className="rounded-md border border-border px-3 py-1.5 font-medium hover:bg-muted"
        >
          Fix underlying issue
        </button>
      </div>
      <ModeErrorBoundary>
        <ResultSurface shouldThrow={shouldThrow} />
      </ModeErrorBoundary>
      <p className="text-xs text-muted-foreground">
        Break → the boundary catches it. Then Fix, and click the boundary&apos;s Reset to recover.
      </p>
    </div>
  );
}
```

Installation [#installation]

```bash
npx shadcn@latest add @localmode/ui/results/mode-error-boundary
```

Dependencies [#dependencies]

* **Data source:** none — it wraps children and catches their render errors. Works in any React app.
* `clsx` + `tailwind-merge` — via the shared `cn()` util (installed automatically as a registry dependency)

Files installed [#files-installed]

* `mode-error-boundary.tsx` — the component
* `lib/utils.ts` — the `cn()` helper (if not already present)

Props [#props]

**ModeErrorBoundary**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | — | **Required.** The subtree to isolate — a render error inside it is caught and recovered. |

Examples [#examples]

Isolate a result surface [#isolate-a-result-surface]

```tsx
import { ModeErrorBoundary } from '@/components/mode-error-boundary';

export function Mode({ data }) {
  return (
    <ModeErrorBoundary>
      <ResultSurface data={data} />
    </ModeErrorBoundary>
  );
}
```

Reset on input change [#reset-on-input-change]

Give the boundary a `key` tied to the input so switching inputs remounts it
fresh, clearing any prior error:

```tsx
<ModeErrorBoundary key={activeMode}>
  <ResultSurface data={data} />
</ModeErrorBoundary>
```

Customization [#customization]

The fallback notice uses `destructive` token utilities. Because you own the
copied file, you can change the message, add error logging in
`getDerivedStateFromError` / `componentDidCatch`, or replace the Reset button
with your own recovery affordance.