I think I understand where the error is occurring but I am able to work out the correct handling flow for a Promise returned from fetch()
My Messages reducer module: -
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() simply returns a promise: -
export const fetchMessages = () => {
return fetch(baseUrl + 'messages')
}
I am not going to post the component code here because it is not relevant to the issue.
So if I call fetchMessages() with an invalid URL to return a 404, state.messages becomes undefined in my component. This would seem to be being caused by this part of the function: -
if (!r.ok) {
dispatch(fetchingMessagesFailure(ERROR_MESSAGE))
}else{
return r.json()
}
I think I might be confused regarding how to properly check and deal with potential errors in the returned Promise. According to the docs for fetch(), a 404 is not considered to be an error as (unlike regular AJAX) only network issues are considered to be a catch() type of error.
Can anyone pinpoint for me what is wrong with this part of my code? should I be using exit after dispatch(fetchingMessagesFailure(ERROR_MESSAGE)) to stop the following .then()? Also, even with just a 404, the .catch() block is also being run. This seems to be against what the docs suggest.
Any help greatly appreciated. Thanks.