Synthetic Industry

Troubleshooting guide · updated 2026-10-11

A white screen or a spinner that never stops? What React error boundaries catch, and the cases they do not

An error boundary covers errors thrown while rendering. Request failures, empty results and errors in event handlers need their own handling, or users see a blank page.

Why a failed request can leave a blank page or an endless spinner

A screen is usually written for the case where data arrives in the expected shape. A typical component keeps a loading flag, sets it when a request starts and clears it when data arrives. If the request fails, times out or returns something unexpected, the clearing code may never run, so the spinner stays. If the code reads a field that is missing and throws while rendering, React removes the app's UI by default, so the whole page can go white. Both are consequences of unhandled cases, not of a particular library.

  • Spinner never stops: the failure path does not clear the loading state.
  • White page: an error was thrown while rendering and nothing caught it.
  • Broken-looking list: the empty case was never designed.

What an error boundary does and does not catch

React's documentation defines an error boundary as a component that shows a fallback for errors thrown while rendering its children, using getDerivedStateFromError to switch to the fallback and optionally componentDidCatch to log. It lists what boundaries do not catch: errors in event handlers, asynchronous code such as timer callbacks, server-side rendering, and errors thrown in the boundary itself. Errors thrown inside a startTransition function are caught. There is currently no way to write a boundary as a function component, so teams use a class or a package such as react-error-boundary. Next.js builds the same idea into its error file convention for route segments.

The practical rule: a boundary is the last line of defence for rendering faults, and the ordinary failures of real life (a failed request, a timeout, an empty list) should be handled where they happen.

  • Put a boundary around each major screen area, not around every component.
  • Do not rely on a boundary for a failed click handler or an unawaited promise.

Expected errors are values, not exceptions

Next.js separates expected errors from uncaught exceptions. Expected errors, such as a failed request or a validation failure, should be handled explicitly and returned to the client, not thrown. For a Server Function it suggests returning an error value that the component shows; for a Server Component it suggests checking the response and rendering a message or redirecting. Uncaught exceptions, which indicate bugs, are thrown and caught by a boundary. For event handlers and async code the guidance is to catch the error yourself and keep it in state, then render a message.

  • Model each outcome of a request: loading, success, empty, failed, timed out.
  • Show a message that tells the user what to do next, with a retry for safe reads.
  • Keep raw error text and technical detail out of the interface.

A seven-case checklist for one screen

For one screen, write the cases before changing code: loading; success; empty; request failed; timeout; server error; and a response that is missing an expected field. For each, decide what the user should see and what controls remain. Then simulate each response in a test, rather than waiting for production to produce it. Status messages that appear without a page change, such as "could not load, try again", should be announced by assistive technology without moving focus, which W3C's 4.1.3 describes.

  • The worked example shows a synthetic states matrix with a response, a screen and a test for each case.
  • A retry should repeat only a read; a failed write needs a separate decision.

What the paid job covers and how it is accepted

Our screen-states job (posted test price £245, untested, paid only after sign-off) takes one screen, or a list and its detail pair, in an existing React or Next.js app and seven agreed cases. It handles each case where the request lives, adds one boundary with retry for rendering faults, and writes a test per case using simulated responses. It is accepted when each case shows its agreed screen, no case leaves a blank page or an unending spinner, a forced rendering failure shows the boundary message and retry restores the screen, and you sign off. It does not repair the service behind the screen. Send the screen, what users see when it fails and the framework in your first enquiry, not customer data or credentials.

Sources and limits

  • React: Component (error boundaries) Checked 2026-10-11.
    • By default a rendering error removes the app's UI; an error boundary shows a fallback for errors thrown while rendering its children using getDerivedStateFromError and componentDidCatch; boundaries do not catch errors in event handlers, asynchronous code such as timers, server-side rendering or the boundary itself; errors thrown inside a startTransition function are caught; there is currently no way to write a boundary as a function component, and the react-error-boundary package is suggested.
  • Next.js: Error handling (documentation version 16.4.0) Checked 2026-10-11.
    • Expected errors, such as failed requests and form validation, should be modelled as return values and shown; uncaught exceptions are caught by error boundaries created with an error file in a route segment; errors in event handlers and async code are not caught by boundaries and should be caught manually and stored in state; a global error file replaces the root layout when active.
  • W3C: Understanding 4.1.3 Status Messages Checked 2026-10-11.
    • Status messages such as errors and progress should be exposed through role or properties so assistive technology can announce them without moving focus.