denden
denden

Reputation: 1319

Handling fetch errors in react native / redux

I've set up my login action creator as follows.

A successful login happens in the try block with a 200 status. All failed logins end up in the catch block 401 and if I shutdown the server, the request returns Network Error.

Is there a better/standard way to handle this? Particularly because in a large application, there are obviously many different endpoints to request from, so it seems un-necessary to re-write the network error code each time.

export const handleLogin = data => async (dispatch) => {
  try {
    const res = await axios.post(
        `http://${SERVERURL}/auth/login`, data
    );
    console.log('200 status');
    dispatch({ type: LOGIN_SUCCESS, payload: res.data });
    // AsyncStorage.setItem(JWT_BEARER_TOKEN, res.data.token);
  } catch (e) {
    if (e.response && e.response.status === 401) {
      console.log('Login Failed');
      dispatch({ type: LOGIN_FAILURE, payload: e.response.data });
    } else {
      console.error('Server / Network Error');
      dispatch({ type: NETWORK_ERROR, payload: e.response });
    }
  }
};

Update based on @Pritish Vaidya's answer.

So using your suggested answer, should I be handling login success fail like so?

export const handleLogin = data => async (dispatch) => {
  const res = await axiosInstance.post('/auth/login', data);
  if (res.status && res.status === 200) {
    dispatch({ type: LOGIN_SUCCESS, payload: res.data });
  } else {
    dispatch({ type: LOGIN_FAILURE, payload: null });
  }
};

And figuring out how I can pass dispatch following the Network Error like here:

// ...
}, (error) => {
  if (!error.response) {
    return dispatch({ type: 'NETWORK_FAILURE' payload: null });
  }
}
// ...

Upvotes: 1

Views: 758

Answers (1)

Pritish Vaidya
Pritish Vaidya

Reputation: 22209

Since you're already using axios, you can handle the errors in the following way.

Axios provides with the request middlewares / interceptors, with an easy implementation.

Based on your question, you need a response middleware

Usage

Interceptor.js

const AxiosInstance = axios.create({
    baseURL: SERVER_URL,
    timeout: 20000,
    headers: {
        'Content-Type': 'application/json'
    }
})


 AxiosInstance.interceptors.response.use((response) =>{
    // handle the response after it is received
    return response;
}, (error) => {
    if (!error.response) {
        // Network error
        // handle the network error here
        // Get the instance of the store here
         store.dispatch(// Your action))
    }
    else {
        // handle the errors due to the status code here
        const code = error.response.status

        // handle the errors due to response data here
        const response = error.response.data
    }

})
export default AxiosInstance

Upvotes: 2

Related Questions