LV1 · 0 XPLog in
Learning path

Lesson 1 of 2 · Resilient Error Handling (try/catch)

try/catch & Error States

Handle request failures deliberately so users receive a useful response rather than a blank screen.

This lesson is locked. You can read ahead, but finish earlier stops to earn progress.

Listen

Watch

Video coming soon

Read

Catch failures that throw

A network request can fail because the user is offline, a server cannot be reached, or the connection is interrupted. Put an awaited request inside try and handle thrown errors in catch. This gives your app a place to recover instead of stopping the interaction with an unhandled error.

js
try {
  const res = await fetch('/api/items');
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const items = await res.json();
} catch (error) {
  console.error('Request failed', error);
}

The example checks res.ok because an important detail surprises many beginners: fetch does not throw just because the server returned 404 or 500. Fetch normally resolves with a response object for those HTTP results. You must check res.ok (or the status code) and handle an unsuccessful response yourself.

Give users a friendly error

Logging is useful for developers, but users need clear feedback. If the request fails, show a message such as “Couldn’t load items. Try again.” Keep the rest of the interface usable where possible. A friendly error state is better than a blank area that leaves the user wondering whether the app is still working.

For your activity, treat both thrown network errors and non-OK HTTP responses as failures. Avoid displaying raw technical details to users; those belong in development diagnostics, while the interface gives a concise next step.

Separate success from failure

Only parse and render the response as successful data after checking the status. If the response body is not valid JSON, parsing can also fail and enter the catch path. Consider whether the server returns JSON for every status before assuming it does.

The catch handler is a recovery point, not a reason to ignore errors. Use it to update the interface, preserve useful diagnostic information during development, and let the user retry when appropriate.

Test more than the happy path

Try a successful request, a deliberately missing route and an offline or interrupted request where practical. Confirm that each failure produces a visible message and that success still renders results. Testing these paths helps your app remain understandable when a request does not go to plan.

Trace try, catch and finally

try runs first. A thrown error jumps to catch, skipping the remaining success lines. finally runs afterward whether the operation succeeded or failed—use it to restore controls or clear a timer, not to announce success.

Practice on your local page with an output element called practice-status:

js
const status = document.getElementById('practice-status');
async function checkRequest(url) {
  if (!status) return;
  status.textContent = 'Loading…';
  try {
    const response = await fetch(url);
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    const data = await response.json();
    status.textContent = 'Response received and parsed';
  } catch {
    status.textContent = 'Could not load this response. Try again.';
  }
}

The important difference from logging alone is that the visitor sees the error. The success message is reached only after both status checking and parsing. In your own dashboard, render actual fields in the success path rather than only this rehearsal label.

Call it first with the known public JSON endpoint from the API lesson. Then use a nonexistent path on that service. Finally use DevTools Offline mode. A 404 is an unsuccessful response; offline is a transport failure; invalid JSON is a parsing failure. All can reach your recovery path, but the diagnosis is different. Restore normal network mode afterward.

A catch block catches errors in its try's awaited work. Calling an async function without awaiting its promise inside that try can leave a rejection outside the intended boundary. Database clients can also return an error object rather than throw; inspect their documented result explicitly.

For the activity, connect a retry control to the same request function. Do not let catch quietly return an empty successful dataset: a genuine zero-row result and a failed load need different messages. Verify the browser page, not only Console, and ensure a subsequent successful attempt replaces the error.

Key terms

try/catch
JavaScript syntax for handling thrown errors.
fetch
A browser API for making network requests.
res.ok
A response property that is true for successful HTTP status codes.
error state
Interface feedback shown when an operation cannot complete.

Summary — copy into your notes

  • Use try/catch for thrown network or parsing errors.
  • Fetch does not throw for a 404; check res.ok.
  • Show a friendly message instead of a blank screen.
  • Test both successful requests and failure paths.