Untitled Lesson
Skill Matrix
UNLOCK NODES BY LEARNING NEW TAGS.
You call `const res = await fetch(url)` against an endpoint that returns HTTP 404. Does the `await fetch(...)` line throw an exception?
💻 Code Challenge | +75 XP
Write an apiRequest(url, options) helper using native fetch that applies a 5-second AbortSignal.timeout, throws a descriptive error on non-ok responses, and returns parsed JSON.
A POST request via fetch() is silently ignored by the server's JSON body parser, which reports an empty body. Reorder the required steps to send valid JSON.
Task: Reorder the blocks in logical sequence to solve the problem.
A.D.A. Interface
Adaptive Didactic Assistant

Pascual Vila
Frontend Instructor // Code Syllabus
The Error //
Assuming fetch() rejects on 4xx/5xx responses like axios does
// Wrong: silently proceeds with an error page as "data"
const res = await fetch(url);
const data = await res.json();
// Correct
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();The Solution //
fetch only rejects its Promise for network-level failures (DNS failure, connection refused, timeout) — an HTTP 404 or 500 is still a "successful" fetch as far as the Promise is concerned, resolving normally with response.ok set to false. Always check response.ok (or response.status) explicitly before trusting the payload.
The Error //
Making an outbound fetch call with no timeout in a request-handling path
// Wrong: no protection against a hanging upstream
await fetch(slowUpstreamUrl);
// Correct
await fetch(slowUpstreamUrl, { signal: AbortSignal.timeout(3000) });The Solution //
Without an explicit AbortSignal.timeout(), a hung upstream dependency can keep a fetch call — and the request handler awaiting it — pending indefinitely, eventually exhausting your server's concurrent connection capacity under load. Every outbound call inside a request handler should carry an explicit timeout appropriate to that dependency's expected latency.