Skip to content

Error Boundaries

Error Boundaries

ErrorBoundary catches errors thrown during render of its subtree and renders a fallback. You can reset the boundary imperatively or by changing a reset_key(s) prop.

from wybthon import ErrorBoundary, h

def Failing(_props):
    raise RuntimeError("boom")

def fallback(err, reset):
    # reset is provided for convenience; you can also use reset_key(s)
    return h("div", {"class": "error"},
             h("p", {}, f"Oops: {err}"),
             h("button", {"on_click": lambda e: reset()}, "Try again"))

view = h(ErrorBoundary, {"fallback": fallback}, h(Failing, {}))

Auto-reset with keys

When a reset_key (single) or reset_keys (list/tuple) value changes, the boundary clears its error and re-renders children on the next render.

from wybthon import ErrorBoundary, h, signal

count = signal(0)

def Counter(_props):
    c = count.get()
    if c % 2 == 1:
        raise ValueError("odd!")
    return h("span", {}, f"Count: {c}")

view = h(
    "div",
    {},
    h(ErrorBoundary, {"fallback": lambda err, reset: h("span", {}, f"Err: {err}")}, h(Counter, {})),
    h("button", {"on_click": lambda e: count.set(count.get() + 1)}, "+1"),
)

# Or couple the boundary to a key so it resets when `count` changes:
view_keyed = h(
    ErrorBoundary,
    {"fallback": lambda err, reset: h("span", {}, f"Err: {err}"), "reset_key": lambda: count.get()},
    h(Counter, {}),
)

on_error hook

Provide on_error to observe errors when they are captured by the boundary:

def on_error(err):
    print("Captured:", err)

view = h(ErrorBoundary, {"fallback": lambda e, r: "Oops", "on_error": on_error}, h(Failing, {}))

Limitations

  • Only errors thrown during render of the child subtree are caught. Errors in event handlers or async tasks should be handled separately.