Hi I have made a wrapper for fetch something like this, I'm importing this wrapper in ponents but on failure catch()
of this wrapper is executing but in the ponent then()
function is executing any idea!!
import { SERVER_URL } from '../configs/serverConfig';
export default function callApi(api_url: string, method = 'get', data = null) {
opts = {
method: method,
headers: {
Authorization: 'Basic VFM0NjA2Omsuc3ZpbTg4',
Accept: 'application/json',
'Content-Type': 'application/json'
}
};
if (data) {
opts.data = JSON.stringify(data);
}
return fetchWrapper(api_url, opts);
}
function fetchWrapper (api_url: string, opts: any){
let requestParamObj= {};
if(opts.method.toLocaleLowerCase() === 'get'){
requestParamObj = {
method:opts.method
}
}
else if(opts.method.toLocaleLowerCase() === 'post'){
requestParamObj = {
method: opts.method,
headers: opts.headers,
body: opts.data
}
}
return (
fetch(api_url, requestParamObj)
.then((resp) => resp.json())
.then(response => {
return response;
})
.catch(error => {
console.log('request failed', error);
return error;
})
)
}
I'm calling this in a ponent something like this
callApi('/someURl', 'GET')
.then((res) => {
console.log('this get called even if api fails', res)
}).catch((err) => {
//TODO :: error handling at global level
console.log('Some err', err)
})
}
Hi I have made a wrapper for fetch something like this, I'm importing this wrapper in ponents but on failure catch()
of this wrapper is executing but in the ponent then()
function is executing any idea!!
import { SERVER_URL } from '../configs/serverConfig';
export default function callApi(api_url: string, method = 'get', data = null) {
opts = {
method: method,
headers: {
Authorization: 'Basic VFM0NjA2Omsuc3ZpbTg4',
Accept: 'application/json',
'Content-Type': 'application/json'
}
};
if (data) {
opts.data = JSON.stringify(data);
}
return fetchWrapper(api_url, opts);
}
function fetchWrapper (api_url: string, opts: any){
let requestParamObj= {};
if(opts.method.toLocaleLowerCase() === 'get'){
requestParamObj = {
method:opts.method
}
}
else if(opts.method.toLocaleLowerCase() === 'post'){
requestParamObj = {
method: opts.method,
headers: opts.headers,
body: opts.data
}
}
return (
fetch(api_url, requestParamObj)
.then((resp) => resp.json())
.then(response => {
return response;
})
.catch(error => {
console.log('request failed', error);
return error;
})
)
}
I'm calling this in a ponent something like this
callApi('/someURl', 'GET')
.then((res) => {
console.log('this get called even if api fails', res)
}).catch((err) => {
//TODO :: error handling at global level
console.log('Some err', err)
})
}
Share
Improve this question
asked Apr 25, 2019 at 8:36
shaanshaan
5246 silver badges26 bronze badges
1
-
What do you have in your
res
var when it's fail, it can help a lot to know what happen ! – ekans Commented Apr 25, 2019 at 8:40
3 Answers
Reset to default 5This is because you're catching the error in the wrapper and returning a value, so the consumer will get the returned value instead of the error.
fetch(api_url, requestParamObj)
.then((resp) => resp.json())
.then(response => {
return response;
})
.catch(error => {
console.log('request failed', error);
throw error;
})
if you replace return error with throw error
the consumer catch will be returned as expected.
PS: Fetch API will resolve the promise even if you get an error status from the API, it will only trigger the catch on actual JavaScript errors, if you want the promise to be rejected on network/API error responses aswell. you might want to do something like this
function handleErrors (response) {
if (!response.ok) {
console.log('ERROR: ' + response)
throw Error(response.statusText)
}
return response
}
and use
.then(handleErrors)
You have two things going wrong.
Firstly, the promise fetch
returns only rejects into catch
if the request fails due to a network error, or in other words - the request never gets to your server. If you get any response, even a HTTP 500, then the promise resolves into then
.
Secondly, like the other answer mentions, if you catch
a promise then that converts the promise chain back into a success mode. You need to throw, or return Promise.reject(value)
to kick the chain back into a failure mode.
Your wrapper would better look like:
return (
fetch(api_url, requestParamObj)
.catch(error => Promise.reject(error)) // Handle network error
.then(response => {
if (!response.ok) {
return Promise.reject(response) // Handle error responses HTTP 4XX, 5XX
} else {
return response.json() // Return success response HTTP 2XX, 3XX
}
})
)
fetch
API rejects the promise if
network error is encountered, although this usually means permissions issues or similar.MDN
In the following example ok
will be logged:
fetch("http://httpstat.us/500")
.then(function() {
console.log("ok");
}).catch(function() {
console.log("error");
});
fetch
provides an ok
flag to check that the response is successful:
fetch("http://httpstat.us/500")
.then(function(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}).then(function(response) {
console.log("ok");
}).catch(function(error) {
console.log(error);
});
Source