Skip to main content
JavaScript & the browser·Module C4 · Lesson 5
TaskWrite fetchJSON(url). Call fetch, check r.ok and throw with HTTP status, parse JSON. Call fetchJSON('/api/ok') and log the returned value. Use try/catch for any errors.

Error handling: network errors vs HTTP errors vs body errors

100 XP9 min
Theory

Three classes of error, all different

try {
  const r = await fetch(url);
  if (!r.ok) throw new Error(\`HTTP ${r.status}\`);
  const data = await r.json();
  if (data.error) throw new Error(data.error);
  return data;
} catch (err) {
  // err here can be any of:
  // - TypeError ("Failed to fetch") → network down, DNS, CORS, offline
  // - your "HTTP 500" Error → server returned bad status
  // - your data.error Error → server returned 200 but body says error
  // - SyntaxError → response body wasn't JSON
}

What you should NOT do

const r = await fetch(url);
const data = await r.json();    // crashes if status was 500 with HTML error page

This is the most common mistake. Server returns a 500 with <html>...error...</html> body. .json() throws SyntaxError because HTML isn't JSON. The error reaches your catch but says "Unexpected token <" which means nothing to anyone.

The honest wrapper

async function fetchJSON(url, options) {
  const r = await fetch(url, options);
  if (!r.ok) {
    const text = await r.text();
    throw new Error(\`HTTP ${r.status}: ${text.slice(0, 200)}\`);
  }
  return r.json();
}

You write this once per project. Every API call goes through it. Errors include the actual status + a snippet of the body so debugging is fast.

Don't show raw errors to users

catch (err) {
  console.error(err);                     // log full detail for you
  showToast("Couldn't save. Try again.");  // generic message for the user
}

"Failed to fetch" is meaningless to users. Map your errors to messages they can act on.

🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 15 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.