Explain Codes LogoExplain Codes Logo

Fetch: reject promise and catch the error if status is not OK?

javascript
async-await
error-handling
promise-rejection
Nikita BarsukovbyNikita Barsukov·Feb 7, 2025
TLDR

Deal with fetch errors swiftly by verifying response.ok. If it's false, throw an Error. Behold:

fetch('url') .then(response => { if (!response.ok) throw Error(response.statusText); // Not OK? Error, please! return response.json(); }) .catch(error => console.error("Oopsie whoopsie, Fetch had a fucky wucky:", error));

The steps: verify status, launch Error if it's adverse, and catch it to manage. Crisp and tidy.

Work with diverse HTTP status codes

The fast answer delivers a quick mechanism to rebuff non-OK responses. But, it can be beneficial to deal with assorted HTTP status codes differently. Behold:

function handleErrors(response) { if (!response.ok) { const error = new Error(response.statusText); error.response = response; throw error; // I ain't afraid of no ghost! } return response; } fetch(url) .then(handleErrors) .then(response => response.json()) .catch(error => console.error('Fetch error:', error));

Login failure use case

If your login request bombshells with a 401 (Unauthorized), you could redirect the user to a login webpage or showcase a dedicated message.

Not found use case

For any 404 (Not Found), you might display a unique message or redirect to a search page since missing resources suggest varying issues.

Server trouble use case

When you encounter 5XX status codes, signaling server errors, consider re-attempting the request or exhibit a "let's try later" message.

Adopting Async/await for better readability

Async/await syntax can enhance readability, making your asynchronous code look synchronous and easier to follow:

async function fetchData(url) { try { const response = await fetch(url); if (!response.ok) throw Error(response.statusText); // If OK is not OK, then...run! const data = await response.json(); return data; } catch (error) { console.error('Fetch error:', error); } }

Better handling with try-catch

Using try-catch blocks that many developers are familiar with makes it easier to manage errors in a way that feels synchronous.

Improved readability

The absence of .then() chains contributes to cleaner, more streamlined code, particularly when dealing with complex logic.

Better error handling

By throwing an Error within the try block, you implicitly reject the Promise, which can then be caught in the catch block.

Systematic error handling

Systematic error handling involves developing uniform rules or functions to handle response cases uniformly.

function errorHandler(status) { switch (status) { case 400: return 'Bad Request'; case 401: return 'Unauthorized. Redirecting to login...'; // The doors are locked! case 404: return 'Resource not found. Try searching for it.'; // They see me looking, they hatin', patrolin' tryin' to catch me ridin'! // ...more cases as needed default: return 'An unknown error occurred'; // An unknown enemy appears! } } fetch(url) .then(response => response.ok ? response.json() : Promise.reject(errorHandler(response.status))) .catch(error => console.error(error));

By associating specific messages to HTTP status codes, users receive more valuable feedback. This approach ensures that we account for known problems and have a system in place for the unexpected. It's also scalable, making the addition of future cases easy as your application evolves.