Why is my `fetch` call not throwing on a 404 or 500 response?

asked 2 months ago496 viewsen

7
try {
  const res = await fetch('/api/user/999');
  const data = await res.json();
} catch (e) {
  console.log('error');
}

The endpoint returns 404 but my catch never runs. Then res.json() fails with a confusing error.

AI diagnosis

AI-generated. Not an answer — the community below confirms or corrects it. Always verify before relying on it.

asked 2 months ago

2 Answers

4
✓
✓ Accepted answer

fetch only rejects on network failures (DNS error, offline, CORS block). Any HTTP response, including 404 and 500, is a *successful* fetch. You have to check res.ok yourself:

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

Wrap this once and use it everywhere. The res.json() error you see is because the 404 body is HTML or empty, not JSON.

Sign in to tell others whether this worked.

answered 2 months ago
2

If you use this pattern a lot, a tiny wrapper library like ky or ofetch throws on non-2xx by default and adds retries and timeouts. Worth it if you don't want to maintain your own helper.

Sign in to tell others whether this worked.

answered 2 months ago

Sign in and verify your email to post an answer.