Ramonda

Error boundaries

If something goes wrong while a component is rendering, that error would normally break the whole page. An error boundary catches it, keeps the rest of the page working, and shows a fallback in place of the broken part.

<ErrorBoundary
  fallback={({ message, reset }) => (
    <p className="error">
      Something broke: {message} <button onclick={reset}>try again</button>
    </p>
  )}
>
  <ReportView data={this.data} />
</ErrorBoundary>

this row is outside the boundary

Fragile is fine.

Break the Report and everything outside the boundary keeps working. So put boundaries around the parts of a page that can fail on their own — a widget, a panel, a route — rather than one at the very top.

The fallback is a function

It receives:

messagethe error message
errthe Error itself, if there was one
resetclears the boundary and tries rendering the subtree again

reset is why it is a function: without it, a boundary is a dead end and the only way back is a page reload. Note that reset re-renders the same subtree, so if the cause is still there it will throw again — fix the cause, then reset.

What it catches

Anything thrown on a path the framework is running: render(), @created, a @compute a render read, and the commit phase that follows — @mounted, @updated, a subscription's connect. All of those go through the framework, so the error can be walked up to the nearest boundary.

It does not catch:

  • Event handlers. The browser calls a listener directly, so a throw inside one never passes through the framework and no boundary can see it. Use try/catch, or put the failure in state.
  • Async work. A rejected promise settles on its own time, with no render around it — catch it and put the failure in state.

The line is not "render versus the rest". It is whether the framework was the one calling.

For loading failures

AsyncLoad has its own errorFallback that plays the same role — a failure UI with a way to retry — so a failed load and a failed render are handled alike. (Its fields are named for a load: { error, retry, attempt } rather than { message, err, reset }.)

Next

  • Lazy loading — loading a component only when it is needed.