API & webhooks
Fetch API GET Request: Add a Timeout and Check the Result
Send a browser GET with a bounded wait, distinguish timeout, HTTP and JSON failures, and keep cancellation separate from automatic retry decisions.
Bound a read without hiding its failure
A browser GET should have a clear result contract and a plan for a response that never arrives. A timeout gives the caller a bounded waiting policy, but it does not turn every failure into the same error or automatically justify another request.
For a small JSON lookup, decide how long the interface should wait and how it should distinguish an HTTP error from a timed-out request. Use a local delayed fixture to test this policy instead of repeatedly sending slow requests to a public service.
Use a timeout signal with fetch
async function getJsonWithTimeout(url, timeoutMs = 5000, fetcher = fetch) {
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 60000) {
throw new Error("Use a timeout from 1 through 60000 milliseconds.");
}
const response = await fetcher(url, {
method: "GET",
headers: {Accept: "application/json"},
signal: AbortSignal.timeout(timeoutMs)
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
The allowed interval is this example's application policy. It is not a limit imposed by the Fetch API. A caller can choose a different policy after considering the endpoint, device and expected payload, but should preserve input validation rather than accepting an accidental infinite or negative wait.
The AbortSignal.timeout reference describes automatic timeout cancellation. In a browser, its timer is based on active time, so suspended contexts can affect elapsed wall-clock observations. It should not be presented as a precise deadline independent of browser lifecycle.
Keep the distinct error paths visible
When the signal times out, the operation can reject with TimeoutError. A readable 404 reaches the explicit status check and produces the HTTP error from this helper. A successful status with malformed JSON fails during parsing. These outcomes call for different explanations in the interface.
A rejected fetch can also arise from a network or browser access problem. Do not label every TypeError as a timeout or assume that retrying changes a server's CORS policy. Inspect the actual error and the relevant network trace in a controlled reproduction.
Remember that receiving headers is not the whole read
The fetch promise can resolve when response headers are available while the body is still arriving. This helper then waits for JSON parsing, and the request's signal still matters while consuming the body. A server that sends headers promptly but stalls its body should be part of the timeout test.
The helper does not impose a body-size cap or validate the JSON's application shape. A small timeout alone is not a memory limit. For large or untrusted responses, choose a bounded streaming strategy and check the data model before displaying it.
Also check the feature support required by the browsers you serve. An environment without AbortSignal.timeout needs an explicitly implemented and tested alternative, such as an AbortController with a cleaned-up timer. Do not catch an unsupported-feature error and silently run the same request without any waiting limit.
Treat user cancellation as a separate decision
If the user navigates away or starts a newer search, the application may need cancellation before the timeout expires. An AbortController can represent that user action, and a supported signal-combining strategy can join it with a timeout. Keep the UI's current-request ownership separate from the network helper.
The Fetch guide describes cancellation and response handling. A cancelled older request must not clear or overwrite a newer request's accepted result merely because its rejection arrives later.
Prove both prompt completion and delayed failure
Test two different successful objects, a readable HTTP error, malformed JSON, a delay before headers and a stall during the body. Use short controlled delays in automated tests and a margin large enough to avoid mistaking scheduling noise for application failure.
After a timeout, issue a fresh valid request and confirm that it succeeds. Check invalid timeout inputs before any network call. The REST API Testing Tool can inspect an authorized endpoint, but its response display does not certify this separate helper's timeout policy or the browser's behavior while suspended.


