Performing Reliable HTTP GET Requests with async/await and fetch in JavaScript
This guide walks you through making reliable HTTP GET requests in JavaScript using async/await and fetch, covering error handling, JSON parsing, request cancellation, and environment setup for browsers and Node.js.
19 Aug 2025, 21:27 UTC

Desired Outcome
By the end of this guide you will be able to perform an HTTP GET request in a browser or Node.js environment, check for HTTP errors, parse JSON safely, cancel long‑running requests, and verify that the code behaves as expected.
Prerequisites
- JavaScript runtime: A modern browser (Chrome 60+, Firefox 55+, Edge 15+, Safari 10+) or Node.js v18.0+ (fetch is built‑in). For older Node.js versions, install
node-fetchas a polyfill. - Basic knowledge of async/await, promises, and try/catch error handling.
- Network access to a public API such as
https://jsonplaceholder.typicode.comfor testing.
Step‑by‑Step Procedure
- Create an async function that will wrap the fetch call. Async functions automatically return a promise and allow the use of
await.async function fetchTodo(id) { // code goes here } - Make the GET request using
fetchandawait. Pass the full URL and optionally setmethodto "GET" (default).const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`); - Check HTTP status.
fetchresolves even for 4xx/5xx responses; you must inspectresponse.okandresponse.status.if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } - Parse the body. Call
response.json()to get a promise that resolves to the parsed object. Handle JSON parse errors separately.let data; try { data = await response.json(); } catch (parseErr) { throw new Error('Failed to parse JSON: ' + parseErr.message); } - Return or use the data.
return data; - Call the async function and handle its promise.
fetchTodo(1) .then(todo => console.log('Todo:', todo)) .catch(err => console.error('Error:', err.message));
Handling HTTP Errors
Because fetch never rejects on HTTP error status, you must explicitly test response.ok. The following table summarizes common status ranges and recommended handling:
| Status | Description | Typical Action |
|---|---|---|
| 1xx | Informational | Usually ignore in browser context |
| 2xx | Success | Proceed to parse body |
| 3xx | Redirection | fetch follows redirects automatically; check final status |
| 4xx | Client error | Log and possibly retry with back‑off |
| 5xx | Server error | Retry after delay; alert user if persistent |
Using AbortController to Cancel Requests
Long‑running requests can be cancelled with AbortController. This is useful for timeouts or when a user navigates away.
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000); // 5‑second timeout
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1', {
signal: controller.signal
});
clearTimeout(timeout);
// process response as before
} catch (err) {
if (err.name === 'AbortError') {
console.warn('Request was aborted by the user or timeout.');
} else {
console.error('Fetch error:', err);
}
}
Running in Node.js
- Node.js v18+ ships with
fetchandAbortControllerbuilt‑in. No extra packages needed. - For Node.js <18, install
node-fetch:
Then import and use it as a drop‑in replacement:npm install node-fetchconst fetch = require('node-fetch'); const AbortController = require('abort-controller');
Verification Checklist
- Run the script in a browser console or Node.js terminal:
node fetch-todo.js. Confirm that the logged object matches the expected JSON fromjsonplaceholder. - Intentionally request a non‑existent resource, e.g.,
https://jsonplaceholder.typicode.com/todos/999999. Verify thatresponse.okisfalseand the error path logs the correct status. - Apply the AbortController with a 1‑second timeout on a slow endpoint (e.g.,
https://httpstat.us/200?sleep=5000). Ensure the catch block logs anAbortErrorand that no data is processed. - In a browser, test a cross‑origin request. If the server does not include the proper
Access-Control-Allow-Originheader, the request will fail with a CORS error; observe the console for the CORS message.
Common Pitfalls and Recovery Options
- Ignoring response.ok: leads to attempts to parse error responses as JSON, producing confusing errors.
- Not handling JSON parse errors: malformed JSON can crash the app if not caught.
- Missing AbortController support in older browsers: use a polyfill or fallback to a simple timeout flag.
- CORS restrictions: ensure the server sets
Access-Control-Allow-Originor use a same‑origin endpoint.
Conclusion
Using async/await with fetch gives concise, readable code for HTTP GET requests. Always validate response.ok, parse JSON within a try/catch, and consider using AbortController for timeouts. In Node.js, fetch is available from v18 onward; earlier versions require node-fetch. Follow the verification checklist to confirm correct behavior, and handle common pitfalls proactively.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.