[英]How to handle errors in fetch() responses with Redux Thunk?
我正在使用isomorphic fetch创建API请求,并使用Redux来处理我的应用程序的状态。
我想通过触发Redux操作来处理互联网连接丢失错误和API错误。
我有以下(工作进行中/坏)代码,但无法找出触发Redux操作的正确方法(而不是仅抛出错误并停止所有操作):
export function createPost(data = {}) {
return dispatch => {
dispatch(requestCreatePost(data))
return fetch(API_URL + data.type, {
credentials: 'same-origin',
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-WP-Nonce': API.nonce
},
body: JSON.stringify(Object.assign({}, data, {status: 'publish'}))
}).catch((err) => {
//HANDLE WHEN HTTP ISN'T EVEN WORKING
return dispatch => Promise.all([
dispatch({type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message:'Error fetching resources', id: h.uniqueId()}),
dispatch({type: PRE_CREATE_API_ENTITY_ERROR, errorType: 'fatal', id: h.uniqueId(), message: 'Entity error before creating'})
])
}).then((req) => {
//HANDLE RESPONSES THAT CONSTITUTE AN ERROR (VIA THEIR HTTP STATUS CODE)
console.log(req);
if (!req || req.status >= 400) {
return dispatch => Promise.all([
dispatch({type: FETCH_RESOURCES_FAIL, errorType: 'warning', message:'Error after fetching resources', id: h.uniqueId()}),
dispatch({type: CREATE_API_ENTITY_ERROR, errorType: 'warning', id: h.uniqueId(), message: 'Entity error whilst creating'})
])
}
else {
return req.json()
}
}).then((json) => {
var returnData = Object.assign({},json,{
type: data.type
});
dispatch(receiveCreatePost(returnData))
})
}
}
如果我无法禁用互联网连接,在JS控制台中,当我通过console.log()(如上所述)登录时,它输出: POST http://example.com/post net::ERR_INTERNET_DISCONNECTED(anonymous function) (dispatch) { return Promise.all([dispatch({ type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message: 'Error fetching resources', id: _CBUtils2.default.uniqueId() }), dispatch({ type:… cb_app_scripts.js?ver=1.0.0:27976 Uncaught (in promise) TypeError: req.json is not a function(…)
请原谅我,如果这是完全错误的,但我不想做任何事情,但是当出现错误时会触发两个Redux动作(一般错误,一个特定于我们在发生错误时执行的操作)。
我正在努力实现的目标是什么?
似乎(通过我的日志记录到控制台)脚本的'then'部分仍在执行(因为它的内容是我的'catch'调度函数)..
我对几件事感到困惑:
Promise.all
来调度两个同步动作? 使用{type: PRE_FETCH_RESOURCES_FAIL, ...}
等调用dispatch
将不会返回Promise,因此Promise.all
是不必要的。 Promise.all()
仅在您发送的操作本身被写为thunk动作创建者时才有用,这不是这里的情况。 return dispatch => ...
只需要在动作创建者的最开始一次。 没有必要在重复这个catch
或then
块,其实,重复它使内部的代码不能执行的。 这是一种将dispatch
注入到顶级函数中的方法,没有必要重复它。 then
一后catch
,它将运行被抓获错误,即使之后。 这不是您想要的行为 - 在错误处理程序之后立即运行成功处理程序是没有意义的。 您希望它们是两个独立的代码路径。 req
”。 它可能应该是res
。 感觉你有一个关于Redux Thunk如何工作的错误心智模型,并试图将不同示例的部分组合在一起直到它点击。 随机缩进也有助于此代码有点难以理解。
这将是一个痛苦的未来,所以我建议得到一个更完整的心理模型Redux Thunk做什么,什么return dispatch => ...
意思,以及Promise如何适应图片。 我会推荐这个答案作为Redux Thunk的深入介绍 。
如果我们修复这些问题,您的代码应该大致相同:
export function createPost(data = {}) {
return dispatch => {
dispatch(requestCreatePost(data));
return fetch(API_URL + data.type, {
credentials: 'same-origin',
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-WP-Nonce': API.nonce
},
body: JSON.stringify(Object.assign({}, data, {status: 'publish'}))
})
// Try to parse the response
.then(response =>
response.json().then(json => ({
status: response.status,
json
})
))
.then(
// Both fetching and parsing succeeded!
({ status, json }) => {
if (status >= 400) {
// Status looks bad
dispatch({type: FETCH_RESOURCES_FAIL, errorType: 'warning', message:'Error after fetching resources', id: h.uniqueId()}),
dispatch({type: CREATE_API_ENTITY_ERROR, errorType: 'warning', id: h.uniqueId(), message: 'Entity error whilst creating'})
} else {
// Status looks good
var returnData = Object.assign({}, json, {
type: data.type
});
dispatch(receiveCreatePost(returnData))
}
},
// Either fetching or parsing failed!
err => {
dispatch({type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message:'Error fetching resources', id: h.uniqueId()}),
dispatch({type: PRE_CREATE_API_ENTITY_ERROR, errorType: 'fatal', id: h.uniqueId(), message: 'Entity error before creating'})
}
);
}
}
解决方案只是(对于错误记录的两个实例)替换:
return dispatch => Promise.all([
dispatch({type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message:'Error fetching resources', id: h.uniqueId()}),
dispatch({type: PRE_CREATE_API_ENTITY_ERROR, errorType: 'fatal', id: h.uniqueId(), message: 'Entity error before creating'})
])```
附:
return Promise.all([
dispatch({type: PRE_FETCH_RESOURCES_FAIL, errorType: 'fatal', message:'Error fetching resources', id: h.uniqueId()}),
dispatch({type: PRE_CREATE_API_ENTITY_ERROR, errorType: 'fatal', id: h.uniqueId(), message: 'Entity error before creating'}),
Promise.reject(err)
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.