The fetch() method in JavaScript is a global, asynchronous method that allows us to interface with API's for requests and responses. While this is a powerful and commonly-used tool, its error handling process may seem a bit elusive at start.
Why Error Handling?
When errors are encountered during a fetch()
call, it is often necessary to halt the compiler from reading the next few lines of code. To do so, the method call should throw an error upon encountering one. The thrown error can be "caught" later on for an alternate behavior to take place. Although one might think that the fetch()
call would automatically throw an error upon encountering one, that is not the case for JavaScript.
According to the fetch() MDN, the Promise object returned by the fetch()
call is rejected (throws an error) only when "a network error is encountered." This means that fetch()
Promises do resolve despite encountering client-side HTTP errors such as 404 and do not throw errors during the fetch. Therefore, the code shown below would log "Success" instead of "Error" when run, which may seem unexpected.
fetch(url) // encounters a 404 error
.then(res => res.json()) // no error is thrown
.then(() => console.log("Success")) //
.catch(() => console.log("Error")) // fails to catch error
Luckily, you can fix this quite simply by using proper error handling.
Handling fetch() Errors
fetch()
calls can be made using either Promise chains or Async/Await. Fortunately, the error handling process is similar for both.
Using Promises
The fetch API provides an ok
property to the Promise response which indicates whether the HTTP status is within the range 200-299 (inclusive). This can be used to check whether any error is encountered during fetch.
const handleError = response => {
if (!response.ok) {
throw Error(response.statusText);
} else {
return response.json();
}
}; //handler function that throws any encountered error
fetch(url)
.then(handleError) // skips to .catch if error is thrown
.then(data => console.log("Does something with data"))
.catch(console.log); // catches the error and logs it
The error-handler function should be called before the Promise response is parsed by
.json()
. Otherwise, the.json()
method would strip out the response properties necessary for error handling (such asok
,status
, andstatusText
).
Using Async/Await
Error handling using Async/Await uses a slightly different syntax, but it also revolves around the idea of using the ok
property to check whether any error is encountered or not.
const response = await fetch(url);
if (!response.ok) {
console.log(response.status, response.statusText);
} else {
const data = await response.json();
console.log(data);
}
The
status
response property provides the status code (e.g. "404") while thestatusText
response property provides the status description (e.g. "Is Not Found").
Conclusion
Although the error handling for fetch()
may not seem intuitive at first, it will later make more sense since it provides the user with more control over unique situations.
Overall, error-handling for fetch()
calls is a simple and user-friendly tool that will definitely aid you in the long-term.
Top comments (1)
First of all, thanks so much for this resource!! It's absolutely awesome and has helped me so much.
Your example has .catch(console.log);
What if I wanted to catch the error and write it to the DOM?