Должен ли я отловить ошибки обещания Redux при отправке или просто обработать их в редукторе?

Поэтому в основном я отправляю действие с помощью thunk и redux-обещания-промежуточного программного обеспечения, которое выполняет вызов API, который возвращает обещание. Затем я отправляю обещание, возвращенное другому создателю действия, в качестве аргумента "полезной нагрузки", который работает с промежуточным программным обеспечением redux-обещания и обрабатывает различные действия MY_ACTION_TYPE_PENDING или MY_ACTION_TYPE_REJECTED или MY_ACTION_TYPE_FULFILLED. Мой вопрос заключается в том, обрабатывать ли я ошибки в редукторе с помощью действия _REJECTED и не перехватывать их в моей рассылке (actionCreator(полезная нагрузка)? Когда я не улавливаю ошибку в своей рассылке, я получаю предупреждение в консоли, несмотря на то, что мой редуктор обрабатывает ошибка с _REJECTED ACTION.

Ниже приведены некоторые из моих действий:

export const RECEIVE_POSTS = 'RECEIVE_POSTS';
export const receivePosts = (data) => ({
    type: RECEIVE_POSTS,
    payload: data
})

// thunk middleware for fetching blog
                    export const fetchPosts = () => { 
                        return (dispatch) => {
                            const payload = contentfulClient.getEntries().then(
                                data => data.items,
                                error => console.log('An error occurred in fetchPost thunk middleware', error)
                                ) 
                            return dispatch(receivePosts(payload))
                            .catch((error) => {
                                console.log('caught error in fetchPost', error)
                            })
                        }
                    }

тогда это - некоторый из моего файла редукторов блога, он обрабатывает действия, которые посылает промежуточное ПО обещания

const status = (state = Status.IDLE, action) => {
    switch (action.type) {
        case `${RECEIVE_POSTS}_PENDING` : 
            return Status.PENDING;      
        case `${RECEIVE_POSTS}_FULFILLED`:
            return Status.FULFILLED;
        case `${RECEIVE_POSTS}_REJECTED`:
            return Status.REJECTED;
        default:
            return state
    }
}

const error = (state = null, action) => {
    switch (action.type) {
    case `${RECEIVE_POSTS}_REJECTED`: 
        return action.payload.message
    default:
        return state;
    }
}

2 ответа

Решение

Это хороший вопрос, и я не думаю, что есть один ответ. В конечном счете, дело за разработчиком или командой разработчиков. Как практика, я бы сказал, да, ошибки обещания должны быть обработаны / обнаружены при отправке. Вот почему...

В вашем примере вы не уловили ошибку обещания. Вы, как вы объяснили, обрабатываете только ошибку в вашем редукторе.

case `${RECEIVE_POSTS}_REJECTED`:
            return Status.REJECTED;

Вы читаете объект с типом ${RECEIVE_POSTS}_REJECTED и написать изменения в состояние. Когда вы записываете изменения в состояние, вы (вероятно, обновляете пользовательский интерфейс и / или отправляете побочные эффекты для обработки ошибки. Это типичная реализация для Redux.

Фактическое обещание, однако, остается неосуществленным в этой реализации. Чтобы поймать ошибку обещания, вы должны сделать это при отправке (или в промежуточном программном обеспечении).

dispatch(myAsyncActionCreator()).catch(function(error) {
  // do something with the error
})

Если вы поймете ошибку при отправке, вы не увидите ошибки в консоли. Подробная, но прямая / явная, эта практика проясняет другим разработчикам, как обрабатываются ошибки. Я полагаю, что ясность важна для ремонтопригодности и будущих изменений, поэтому я и спорю об обнаружении ошибок при отправке.

Надеюсь, это поможет!

Мне легче рассуждать о следовании redux-thunk код по сравнению с redux-promise-middleware автоматические модификации типа... так что публикация в качестве альтернативы, на случай, если другие люди сочтут это сравнение тоже полезным:

export const fetchPosts = () => (dispatch) => {
  dispatch({type: '${RECEIVE_POSTS}_PENDING'})
  contentfulClient.getEntries()
    .then(data => dispatch({type: '${RECEIVE_POSTS}_FULFILLED', payload: data.items})
    .catch(error => dispatch({type: '${RECEIVE_POSTS}_REJECTED', payload: error})})
}
Другие вопросы по тегам