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 10 lessons in each track are free. No card needed for those.