Consider the code below that is supposed to do something when the reply from a web endpoint is "200-ish" (2xx and similar) and something else when the reply is 404 (and yet something else for non-404, and manage network issues)
fetch('https://httpstat.us/404')
.then((r) => {
if (r.ok) {
console.log(`response 200-ish`)
return r // go to the next .then()
} else {
console.log(`response is not 200-ish`)
return Promise.reject(r.status) // the chain for then() breaks here
}
})
.then((r) => {
console.log('do stuff for 200-ish')
})
.catch((err) => {
if (err === 404) {
console.log('do 404 stuff')
} else {
console.log('do stuff because of another response from the API')
}
// how to address network problems??
})
https://httpstat.us/200 the code is OKhttps://httpstat.us/404 the code is OKhttps://httpstat.us/500 (= neither 200 nor 404, but a correct reply from the API server), the code is OK by chancehttps://httpstat.usXXXXXXXX/500 (= an incorrect URL, generating a network error), the code is not OKIn other words the last else catches anything not explicitly checked for.
How can I differentiate between an explicit break from the promise chain (exposing a return code) and network errors?
You will need a slighly complex chain of promises:
let fetchPromise = fetch('https://httpstat.us/404');
fetchPromise.catch((e) => {
// Do stuff only for network errors
});
fetchPromise.then((r) => {
if (r.ok) {
return r.json().then(
/* The JSON here is just a example if you need to wrap more promises */
/* Do something with a 200 */
)
} else {
/* Do something with non-200 ish */
}
})
Alternatively:
try:
let response = await fetch('...');
catch (ex) {
/* do something with network errors */
}
if (!response.ok) {
/* do something with non-network errors */
throw new Error()
}
/* do something with 200 */