Retries with backoff, then a toast
The 503s are retried after 100 ms and 200 ms and the third attempt succeeds. The 403 isn't retryable, so it fails at once with a message that says what it means. Toasts sit in an aria-live region so screen readers announce them. A real toast would also disappear after a few seconds and have a close button.
Decide in advance where each kind of error goes: expected errors (validation, 404, a refused action) are shown inline or as a toast where they happen, unexpected bugs are caught by error boundaries placed at the root, route and widget levels, every error is reported once from a central place, and only temporary failures are retried, with backoff.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a useAsyncAction(fn) hook that returns { run, error, pending }, catches errors from fn, reports them with reportError, and stores a user-facing message.
Add a route-level boundary to a React Router 8 data router so that an error in /orders shows a message inside the layout while the navigation stays.
Explain it without notes
How would you design error handling for a large React app?
Where would you place error boundaries, and why not around every component?
Which errors do error boundaries not catch, and how do you handle those?
When should a failed request be retried, and how?
Preview
Console
Nothing logged yet.Expected console output
attempt 1 failed with HTTP 503 - retrying in 100 ms
attempt 2 failed with HTTP 503 - retrying in 200 ms
Order succeeded
Cancel gave up: HTTP 403