Skip to main content
JavaScript & the browser·Module C7 · Lesson 10
TaskDefine HttpError extends Error (with .status field) and NotFoundError extends HttpError. Write async fetchJson(url) that throws NotFoundError on status 404 and HttpError on any other not-ok. For each id in [1, 999], try fetchJson('/api/users/' + id) — success path logs user.name; instanceof NotFoundError → log 'not found'.

Capstone: typed-error fetch wrapper

250 XP14 min
Theory

The shape every real codebase needs

A fetch wrapper that turns HTTP statuses into typed errors. Every call site gets clean narrowing: 404 → null, anything else not-OK → throw.

class HttpError extends Error {
  constructor(status, statusText) {
    super(\`HTTP ${status} ${statusText}\`);
    this.name = "HttpError";
    this.status = status;
  }
}
class NotFoundError extends HttpError {
  constructor(s, t) { super(s, t); this.name = "NotFoundError"; }
}

async function fetchJson(url) {
  const r = await fetch(url);
  if (r.status === 404) throw new NotFoundError(r.status, r.statusText);
  if (!r.ok)            throw new HttpError(r.status, r.statusText);
  return r.json();
}

Calling it

try {
  const user = await fetchJson("/api/users/1");
  console.log(user.name);
} catch (err) {
  if (err instanceof NotFoundError) return null;
  throw err;  // unknown — let it bubble
}

Why this scales

The pattern extends trivially: class RateLimitError, class BadRequestError, class UnauthorizedError — same five-line shape, each catches its own status. Every API client in your codebase reads the same way.

🔒

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.