I am trying to handle 500 internal server errors inside fetch. If an internal error occurs, the server responds with a message. I want to extract that message.
const req = new Request(url, {
method: node.method,
mode: 'cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
fetch(req)
.then((response) => {
if (response.status === 500) {
// res.json extracts the body from the response as a promise, chain
// .then on it and throw an error to be caught in the lower catch.
response.json()
.then((json) => {
const { message, stackTrace } = json;
throw new ServerException(message, stackTrace); // note 1
})
.catch((error) => {
return Promise.reject(RawException(error)); // note 2
});
} else {
return response.json();
}
})
.then((json) => { // note 3
dispatch(stopLoading());
dispatch(recieveResponse(typeOfRequest, json));
})
.catch((e) => {
dispatch(stopLoading());
dispatch(responseError());
dispatch(showError(e.message));
});
};
My issue is that extracting the body of the response creates a new promise, and I am unable to reject the outer promise from the inner one.
Note 1 triggers the catch method of the inner promise. Inside catch, I have tried throwing another error but it doesn't seem to work. If I throw new RawException(error)
on the second noted line, nothing happens and the then
method on the third noted line triggers. If I return a rejected promise as I have in the code provided, then still triggers but json is undefined.
How do I do this?
500 - Internal server error. There is a problem with the resource you are looking for, and it cannot be displayed. To resolve this issue, set the Enable 32-bit Applications to "False": Open the Internet Information Services (IIS) Manager.
The solution is not to nest promises, but to resolve/return the .then
of the outer promise with the conclusion of the inner promise.
if (response.status === 500) {
response.json() // response.json returns a promise, we chose to do nothing with its
.then((json) => { // conclusion
const { message, stackTrace } = json;
throw new ServerException(message, stackTrace); // note 1
})
.catch((error) => {
return Promise.reject(RawException(error)); // note 2
});
} else {
return response.json();
}
Should become
if (response.status === 500) {
return response.json() // return the result of the inner promise, which is an error
.then((json) => {
const { message, stackTrace } = json;
throw new ServerException(message, stackTrace);
});
} else {
return response.json();
}
The else clause can be removed as well if that syntax is preferred. ESLint complains about the else being wasteful, but I perfer the way it makes the code's branching explicit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With