Reputation: 558
I am using ES6 and trying to handle error status of the fetch()
result.
I know I can catch error like this:
fetch(`http://${this.serverAddress}/reset`)
.then((resp) => {
Logger.debug(JSON.stringify(resp));
})
.catch((err) => {
Logger.debug(JSON.stringify(err));
});
In catch
block I take an Error
with message "Failed to fetch". There is no status information.
I have found the following suggestion:
fetch('/some/url/')
.then(processResponse)
.then(response => {
// do something
})
.catch(response => {
// repsonses with status >= 400 get rejected. you can access response.status and response.data here too
if (response.status === 400) {
// handle form validation errors, response.data.errors...
} else if (response.status === 403) {
// handle permission errors
} // etc
});
But response.status
is undefined in catch
block.
How can I get status code of the error to handle it?
UPDATE:
Thank you for the responces. Please see my updates:
My actual token looks as http://api.service/v2/prices/latest?token=err
. If I write my token instead of err
, then it works. When I try this URL, my code go to the catch
block, not then
.
I noticed the following error in browser console:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 401. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
If I add {mode: "no-cors"}
, code go to the then
, but status is always 0. This is not that I want.
I tried to add
mode: "cors",
headers: {
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json"
}
This is not help, I still have No 'Access-Control-Allow-Origin' header
error.
Upvotes: 0
Views: 1081
Reputation: 1296
As seen in the docs the catch
block will be reached only if the request didn't complete. When there is a status code available (and all the other data is received as well) fetch
will resolve and therefore the then
block will be reached.
The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing. - Source
So all you have to do is logging resp.status
instead of resp
.
fetch(`http://${this.serverAddress}/reset`)
.then((resp) => {
Logger.debug(JSON.stringify(resp.status));
})
.catch((err) => {
Logger.debug(JSON.stringify(err));
});
In catch block I take an Error with message "Failed to fetch". There is no status information.
So in case the catch
block is getting called the request didn't even finish. This might be caused because you are not using options like method
, headers
,... If needed, which one and what values depends on the backend you are using.
Upvotes: 0
Reputation: 439
After the fetch request check if response is as expected. If not, throw new error with a custom message. In the catch check if this custom message is there for the thrown error. Handle accordingly. You can also create custom Errors and check the same.
Upvotes: 0
Reputation: 20734
You may try to handle the error status by throwing error during response processing right after the fetch is done with !ok
:
fetch('/some/url/')
.then(response => {
if (!response.ok) {
throw Error({ status: response.status });
}
response.json();
})
.then(response => {
// do something
})
.catch(error => {
switch(error.status) {
// ...
}
});
Upvotes: 1
Reputation: 8183
You can't check the status in code.
The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.
Basically, fetch() will only reject a promise if a networking error occurs.
The fetch API provides a simple ok flag that indicates whether an HTTP response’s status code is in the successful range or not. See the below example
fetch("http://httpstat.us/500")
.then(function(res) {
if (!res.ok) {
throw Error(res.statusText);
}
return res;
}).then(function(res) {
console.log("ok");
}).catch(function(error) {
console.log(error);
});
Upvotes: 0