fetch-plus
fetch-plus copied to clipboard
Problems reading json() when status > 400
I do a post to a server and receive a 422 error, the body of the response contains a json object with what validations it failed. However, the docs for fetch indicate that the body of the response hasn't been read at the time of the promise rejection. The body is a ReadableByteStream and the only code I've found to read that is this:
var decoder = new TextDecoder();
var reader = response.body.getReader();
// read() returns a promise that resolves
// when a value has been received
reader.read().then(function processResult(result) {
if (result.done) return;
console.log(
decoder.decode(result.value, {stream: true})
);
// Read some more, and recall this function
return reader.read().then(processResult);
});
The JsonPlus middleware doesn't handle it either. What is the correct way to be able to read the response.json() on a rejected fetch?
Code that may need to change in the fetch-plus source: http://stackoverflow.com/questions/29473426/fetch-reject-promise-with-json-error-object
Where I found the code to read the body: https://jakearchibald.com/2016/streams-ftw/
The correct way is to add a middleware with an error handler that returns the rejected value so the promise chain is effectively recovered.
apiClient.addMiddleware((request) => {
return {
error: (response) => {
if (typeof response.json === "function") { // alternatively check the http status code
return response.json(); // return rejected value to recover promise chain
}
throw response; // fatal error
}
};
}));
Should this behavior be (configurable) in the fetch-plus-json
you think?
I'd figured out something similar just moments before I saw your message:
error: response => {
if (response.status == 422) {
return response.json().then(json => Promise.reject({response, json}))
} else {
...
}
}
I didn't get it to work unless I have the Promise.reject() though.
To more closely match the pattern in fetch-plus-json, it should redefine the body property?
Yes, I do think this should be included in the fetch-plus-json as it's a common issue, I'd think.