Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsfetch() does not reject just because a server responds with an HTTP error status such as 404 or 500. It fulfills with a Response, and your code must check response.ok or response.status to decide what to do. To make a non-success status enter a catch path, throw an error after receiving the response.
Why fetch resolves for a 404 or 500
An HTTP status describes the server’s response to a request. Even when that status indicates a problem, the browser has received an HTTP response, so Fetch fulfills with a Response rather than treating the status itself as a request failure. The MDN fetch() documentation calls out this behavior; the WHATWG Fetch Standard distinguishes ordinary responses from network errors.
A fulfilled promise therefore means that Fetch obtained a response—not necessarily that the operation succeeded according to your application. Use response.ok to test whether the status is in the 200 range, or response.status when your logic depends on a particular code.
Make HTTP errors reject when that fits your function
Check the response immediately after fetch() fulfills. Throwing is an application choice: Fetch did not reject for the HTTP status; your code turns the status into an exception.
#1 Best Overall
async function getData(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return response.json();
}
A surrounding try/catch can handle the error you throw here, as well as request, cancellation, or body-processing errors that reject independently. The MDN Fetch API guide documents this status-check pattern.
Choose whether to return the response or throw
There is no single right policy for every API wrapper. Decide based on what callers need and what your function promises to return.
Rank #2
- TypeScript implements a superset of syntax for strictly typed development, facilitating deep static analysis and enhanced development environment integration. The compiler translates source into standard script formats, ensuring parity across any runtime.
- TypeScript is ideal for front-end developers, full-stack engineers, and software architects who build large-scale web applications. It serves those looking to improve code excellence, reduce bugs through static checking, and maintain complex projects more.
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
| Approach | Use it when | What the caller receives |
|---|---|---|
Return the Response without throwing for its status |
The caller needs to branch on multiple statuses or inspect an error response body. | A response for both successful and non-success HTTP statuses; the caller checks ok or status. |
Throw when response.ok is false |
The function is meant to return successful data only and callers use exceptions for failures. | Parsed data for an OK status, or a rejected promise for an HTTP status your code chose to treat as an error. |
If an error response contains useful validation or diagnostic details, read and preserve them before throwing, for example in a typed error. Do not assume the body is JSON: its format depends on the server’s API contract.
Use the status when different failures need different behavior
response.ok is convenient when every status outside the 200 range follows the same path. When the application needs more specific behavior, inspect response.status: a product might show a sign-in prompt for an authorization response, a not-found view for a missing resource, or a retry option for a temporary server failure. Fetch does not impose those policies.
The MDN guide describes Response.status as the numeric status code and Response.ok as true for a status in the 200 range.
Separate HTTP statuses from other failure stages
Not every problem appears as a non-success HTTP response, and not every rejected promise represents an HTTP status. The stage where a failure occurs determines what your code can inspect.
- Non-success HTTP response:
fetch()fulfills with aResponse. Checkokorstatusand apply your own policy. - Request-level failure: A network failure or malformed URL or scheme can reject the fetch promise, so there may be no usable HTTP response to inspect.
- Cancellation: Aborting a request can reject with an
AbortError. If you abort after the response arrives but before reading its body, a later body read can reject instead. See MDN’s cancellation guidance. - Body consumption or parsing:
response.json(),response.text(), and other body reads are separate asynchronous operations. They can fail after Fetch has delivered a response; for example, malformed JSON can make JSON parsing fail even when the status is in the success range.
Why a status of 0 is not an HTTP error code
Do not treat every response.status === 0 as a server-returned HTTP status. Some filtered responses, including opaque and opaqueredirect responses, expose restricted information and report status 0. The MDN Response.type documentation explains these response types. If you see status 0, examine the request mode and redirect handling rather than assuming the server sent an ordinary HTTP error response.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




