问题
I have the following promise chain:
return fetch(request)
.then(checkStatus)
.then(response => response.json())
.then(json => ({ response: json }))
.catch(error => ({ error }))
Where checkstatus()
checks if the request was successful, and returns an error if it wasn't. This error will be caught and returned. But, the problem is that I want to add the both response.statusText
and the results of response.json()
to the error. The problem is that when I parse it I lose the original response in the chain since I have to return response.json()
because it's a promise.
This is what checkstatus does currently:
const checkStatus = response => {
if (response.ok) return response
const error = new Error('Response is not ok')
// this works because the response hasn't been parsed yet
if (response.statusText) error.message = response.statusText
// an error response from our api will include errors, but these are
// not available here since response.json() hasn't been called
if (response.errors) error.errors = response.errors
throw error
}
export default checkStatus
How do I return an error with error.message = response.statusText
and error.errors = response.json().errors
?
回答1:
Here's my helper for sane fetch
error handling, fetchOk:
let fetchOk = (...args) => fetch(...args)
.then(res => res.ok ? res : res.json().then(data => {
throw Object.assign(new Error(data.error_message), {name: res.statusText});
}));
Which I then substitute for fetch.
let fetchOk = (...args) => fetch(...args)
.then(res => res.ok ? res : res.json().then(data => {
throw Object.assign(new Error(data.error_message), {name: res.statusText});
}));
fetchOk("https://api.stackexchange.com/2.2/blah")
.then(response => response.json())
.catch(e => console.log(e)); // Bad Request: no method found with this name
var console = { log: msg => div.innerHTML += msg + "<br>" };
<div id="div"></div>
It doesn't load the data unless there's an error, making it a direct replacement.
回答2:
I use the new async/await syntax, since that reads in a more intuitive way:
async fetchData(request) {
try {
const response = await fetch(request)
const data = await response.json()
// return the data if the response was ok
if (response.ok) return { data }
// otherwise return an error with the error data
const error = new Error(response.statusText)
if (data.errors) error.errors = data.errors
throw error
} catch (error) {
return { error }
}
}
It makes it very easy to handle both the promise that fetch
returns as well as the promise that response.json()
returns.
来源:https://stackoverflow.com/questions/41505489/how-to-include-both-a-parsed-response-and-original-response-headers-in-fetch-err