Search code examples
reactjstypescriptreduxaxios

Axios error handling the err.response object


I have an React/Redux action creator which makes a post request on creation of a new user's account.

When I test the server validation I am expecting the err.response object inside the catch to be defined and return the validation error message. However, the err.response and err.request objects are not defined and I am getting the generic "An internal error occurred" when the user should be seeing the validation error instead.

I have followed the setup they recommended at https://github.com/axios/axios#handling-errors, however I've found no luck. Any idea?

import { REGISTER_SUCCESS, REGISTER_FAILED, RegisterReq, TokenRes } from "./types";
import { returnErrors } from "../errors/actions";
import { Config } from "../../utils/tokenConfig";
import axios, { AxiosResponse, AxiosError } from "axios";

export const registerUser = (user: RegisterReq) => (dispatch:Function):void => {
    const config: Config = {
        headers: {
            "Content-Type": "application/json"
        },
        withCredentials: false
    };

    axios.post<TokenRes>("/v1/users", user, config)
        .then((res: AxiosResponse<TokenRes>):void => dispatch({
            type: REGISTER_SUCCESS,
            payload: res.data
        }))
        .catch((err: AxiosError):void => {
            if(err.response) dispatch(returnErrors(err.response.data, err.response.status, REGISTER_FAILED));
            
            else if(err.request) dispatch(returnErrors(err.request.data, err.request.status, REGISTER_FAILED));
         
            dispatch(returnErrors("An internal error occurred", 500, REGISTER_FAILED));
        });
};

Solution

  • So it seems that the err properties are actually defined, but my component is rendering multiple times, which makes it return the generic error. This makes it look like the AxiosError properties are undefined. Redux Devtools State Changes

    Inside the catch callback, just add an else to the final dispatch

    .catch((err: AxiosError):void => {
        if(err.response) dispatch(returnErrors(err.response.data, err.response.status, REGISTER_FAILED));
                
        else if(err.request) dispatch(returnErrors(err.request.data, err.request.status, REGISTER_FAILED));
             
        else dispatch(returnErrors("An internal error occurred", 500, REGISTER_FAILED));
    });