React、Immutable、fetch() - 不正确的错误处理导致未定义的状态元素?

React, Immutable, fetch() - incorrect error handling leading to undefined state element?

我想我明白哪里发生了错误,但我能够为Promise计算出正确的处理流程return来自 fetch()

我的消息减速器模块:-

import { fetchMessages } from '_helpers/api'
import { Map, fromJS } from 'immutable'

const FETCHING_MESSAGES = 'FETCHING_MESSAGES'
const FETCHING_MESSAGES_FAILURE = 'FETCHING_MESSAGES_FAILURE'
const FETCHING_MESSAGES_SUCCESS = 'FETCHING_MESSAGES_SUCCESS'
const ADD_MESSAGES = 'ADD_MESSAGES'

const ERROR_MESSAGE = 'There has been an error'

export const fetchAndHandleMessages = () => {

  return (dispatch, getState) => {

    dispatch(fetchingMessages())

    fetchMessages()
      .then((r) => {
        if (!r.ok) {
          dispatch(fetchingMessagesFailure(ERROR_MESSAGE))
        }else{
          return r.json()
        }
      })
      .then((b) => {
        dispatch(fetchingMessagesSuccess(b))
      })
      .catch(() => {
        dispatch(fetchingMessagesFailure(ERROR_MESSAGE))
      })
  }
}

function fetchingMessagesSuccess(messages) {
  return {
    type: FETCHING_MESSAGES_SUCCESS,
    messages,
    lastUpdated: Date.now(),
  }
}

function fetchingMessagesFailure(errMsg) {
  return {
    type: FETCHING_MESSAGES_FAILURE,
    error: errMsg
  }
}

const fetchingMessages = () => {
  return {
    type: FETCHING_MESSAGES,
  }
}

const initialState = fromJS({
  messages: [],
  isFetching: true,
  error: '',
})

export const messagesReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCHING_MESSAGES :
      return state.merge({
        isFetching: true,
      })
    case FETCHING_MESSAGES_SUCCESS :
      return state.merge({
        error: '',
        isFetching: false,
        messages: action.messages
      })
    case FETCHING_MESSAGES_FAILURE:
      return state.merge({
        error: action.error,
        isFetching: false
      })
    default :
      return state
  }
}

export default messagesReducer

fetchMessages() 只是 return 一个承诺:-

export const fetchMessages = () => {
  return fetch(baseUrl + 'messages')
}

我不会post这里的组件代码,因为它与问题无关。

因此,如果我使用无效的 URL 调用 fetchMessages() 到 return 404,state.messages 在我的组件中变为 undefined。这似乎是由函数的这一部分引起的:-

        if (!r.ok) {
          dispatch(fetchingMessagesFailure(ERROR_MESSAGE))
        }else{
          return r.json()
        }

我想我可能对如何正确检查和处理 returned Promise 中的潜在错误感到困惑。根据 fetch() 的文档,404 不被视为错误,因为(与常规 AJAX 不同)只有网络问题才被视为 catch() 类型的错误。

任何人都可以为我指出这部分代码有什么问题吗?我应该在 dispatch(fetchingMessagesFailure(ERROR_MESSAGE)) 之后使用 exit 来停止以下 .then() ?此外,即使只有 404,.catch() 块也是 运行。这似乎违背了文档的建议。

非常感谢任何帮助。谢谢

我看到你在 !r.okcatch 上使用相同的操作...所以我建议在 !r.ok 的情况下通过抛出错误来打破链条:

fetchMessages()
  .then((r) => {
    if (!r.ok) {
      throw true; // just go to .catch()
    }
    return r.json()
  })
  .then((b) => dispatch(fetchingMessagesSuccess(b)))
  .catch(() => dispatch(fetchingMessagesFailure(ERROR_MESSAGE)))