Error Boundary

Catches errors thrown inside reactive child expressions and renders a fallback element instead of crashing the whole tree. Apply to any container element.

Only errors in reactive children (functions returning element arrays) are caught. Errors during static construction propagate normally — those are programming errors, not runtime data errors.

Props

PropTypeDefaultDescription
fallbackDomphyElement | ((error, reset) => DomphyElement){ div: "An error occurred." }Fallback element shown when a child throws. Pass a factory to receive the error and a reset callback.
onError(error: unknown) => voidOptional callback invoked on every caught error, useful for logging and telemetry.

Basic fallback

Provide a static element as fallback for a simple message when you do not need to display the error or offer a retry:

{
  div: (l) => renderUserContent(l),
  $: [errorBoundary({ fallback: { p: "Something went wrong." } })],
}

Factory fallback with reset

Pass a function to receive the thrown error and a reset callback. Calling reset() clears the boundary so the next reactive evaluation runs again:

{
  div: (l) => dataState.get(l).map(renderItem),
  $: [
    errorBoundary({
      fallback: (error, reset) => ({
        div: [
          { p: `Error: ${String(error)}` },
          { button: "Try again", onClick: reset },
        ],
      }),
    }),
  ],
}

With error logging

Use onError to forward errors to your monitoring stack while still showing a friendly fallback:

{
  section: (l) => renderDashboard(l),
  $: [
    errorBoundary({
      fallback: { div: "Dashboard failed to load." },
      onError: (error) => reportToSentry(error),
    }),
  ],
}
Customization

Must see the source of patch at the bottom of each patch page to understand the structure then code it still code as html native element.

There are four levels of customization, in increasing order of effort:

  1. Patch props. Each patch exposes a small, stable set of props—typically fewer than five. Lowest friction.
  2. Context attributes. Use dataTone, dataSize, and dataDensity on a container to shift tone, size, or density for an entire subtree without touching individual elements.
  3. Inline override. Native-wins merge strategy: any property set directly on the element overrides the patch value.
  4. Create a variant. Clone a similar patch and edit it. Use this only when you need a reusable custom version.
Formulas

Unit - U = fontSize / 4 - convert final values with themeSpacing(n).

Size - n = intrinsic text lines, w = wrapping level, d = density factor:

height        = (n * 6 + 2 * d * w) * U
paddingBlock  = d * w * U
paddingInline = ceil(3 / w) * d * w * U
radius        = d * w * U

Base density d = 1.5:

Uw=0w=1w=2w=3
height (n = 1)691215
paddingBlock01.534.5
paddingInline34.564.5
radius01.534.5

Tone - K = N / 2 where N is the palette length. For N = 18, K = 9.

RoleShiftn=0
Backgroundparent +/- n0
Textbg + K6
Borderbg + K/23
Hoverbg + 2K/34
Selected / Focusabove +/- K/32-4

State shift range: K/3 <= delta <= 2K/3.

<div class="blocks">
<div class="block active" data-tab="0">
import type { DomphyElement, PartialElement } from "@domphy/core";

/**
 * Catches errors thrown inside reactive child expressions and renders a
 * fallback element instead of crashing the whole tree. Apply to any container.
 *
 * Only errors in *reactive* children (functions returning element arrays) are
 * caught. Errors during static construction propagate normally — those are
 * programming errors, not runtime data errors.
 *
 * @hostTag any
 * @param props.fallback - Fallback element or factory `(error, reset) => element`. Defaults to a plain error message div.
 * @param props.onError - Optional callback for logging/telemetry.
 * @example { div: (l) => renderUserContent(l), $: [errorBoundary({ fallback: { p: "Something went wrong." } })] }
 */
function errorBoundary(
  props: {
    fallback?:
      | DomphyElement
      | ((error: unknown, reset: () => void) => DomphyElement);
    onError?: (error: unknown) => void;
  } = {},
): PartialElement {
  return {
    _onError: (node, error, reset) => {
      props.onError?.(error);
      const fallbackEl =
        typeof props.fallback === "function"
          ? props.fallback(error, reset)
          : (props.fallback ??
            ({ div: "An error occurred." } as DomphyElement));
      node.children.update([fallbackEl]);
    },
  };
}

export { errorBoundary };
</div>
</div>