Error class for non-ok HTTP responses from the Fetch API. Captures the response body as text and JSON for debugging.
$ npm install @stores.com/http-error
const HttpError = require('@stores.com/http-error');
const response = await fetch('https://api.example.com/items');
if (!response.ok) {
throw await HttpError.from(response);
}Catching errors:
try {
const response = await fetch('https://api.example.com/items');
if (!response.ok) {
throw await HttpError.from(response);
}
} catch (err) {
console.error(err.message); // "404 Not Found" — or aggregated body errors[].message values
console.error(err.text); // Raw response body
console.error(err.json); // Parsed JSON (if applicable)
console.error(err.cause); // Original Response object
}Some APIs carry application-level failures in the response body rather than (or in addition to) HTTP status codes. from() reads the body and aggregates an errors[] envelope into the message automatically — for each entry, the first present of message or detail is used, joined by ; . Codes and any other per-error fields stay on err.json.errors[].
const response = await fetch('https://api.example.com/graphql', { /* ... */ });
if (!response.ok) {
throw await HttpError.from(response);
}
const json = await response.json();
if (json?.errors?.length) {
throw await HttpError.from(response);
}
return json;The default "${status} ${statusText}" message is used when from() can't read the body (already consumed) or when the body has no errors[].
This covers two widely used envelope shapes:
- GraphQL — every response error entry includes a
messagestring. Servers return 200 OK with a top-levelerrors[]for both partial and total failures. The same envelope is used by many REST APIs that signal application-level failures in the body rather than (or in addition to) HTTP status codes. - JSON:API — error objects use
detailfor the per-occurrence explanation.
Creates an error with message "${status} ${statusText}" and sets cause to the response.
Async factory that creates an HttpError and captures the response body:
err.text— the response body as a stringerr.json— the parsed JSON (if the body is valid JSON)err.cause— the originalResponseobject
The original response is not consumed (uses response.clone()).
If the parsed body carries an errors[] array, err.message is set to each entry's message or detail (whichever is present, in that order) joined by ; instead of the default "${status} ${statusText}". See APIs that return errors in the body above.