How to catch the cancellation error on an Axios request? (Custom Hook)

763 Views Asked by At

I'm building a custom hook for fetching data with Axios.

When the request is cancelled before the response is received, you will get a cancellation error that couldn't be fetched within the try/catch block. I am able to catch it right after the request with .catch, but then you have two places where you're are handeling the errors and we're mixing then/catch (ES6) and try/catch (ES7) syntax. Any suggestions on how to fix this?

  • I use the abort controller method as suggested in the Axios documentation

  • The setTimeout functions are for debugging purpose.

const useFetch = ( dataUrl ) => {
    // Set initial state variables
    const [ data, setData ] = useState( [] );
    const [ catchError, setCatchError ] = useState( null );
    const [ isLoading, setIsLoading ] = useState( false );

    const controllerRef = useRef( false );

    // Run the effect on mount
    useEffect( () => {
        let isMounted = true;

        // Define request cancellation signal
        const controller = new AbortController();
        const { signal } = controller;

        // Fetch data function declaration
        const fetchData = async ( url ) => {
            setIsLoading( true );
            try {
                // Fetch the response
                setTimeout( async () => {
                    const response = await axios.get( url, {
                        signal
                    } )
                        // Catch cancellation error (couldn't be fetched in the catch block)
                        .catch( e => e.code === "ERR_CANCELED" && console.log( "Fetch Request Cancelled" ) );
                // Set the data
                if ( isMounted ) {
                    setData( response.data );
                    setCatchError( null );
                }
                }, 2000 )
            } catch ( err ) {
                // Catch the error
                if ( isMounted ) {
                    setCatchError( err.message );
                    setData( [] );
                }
            } finally {
                // Set loading to initial state
                isMounted && setTimeout( () => setIsLoading( false ), 2000 );
            }
        }
        // Call the Fetch Data function
        fetchData( dataUrl )

        // Cleanup the request on cancellation
        return function cleanUp() {
            console.log( 'Clean up function' );
            isMounted = false;
            controller.abort();
        };
    }, [ dataUrl ] );

    return { data, catchError, isLoading };
}

export default useFetch;

In other words, how can I fetch the error displayed below within the try/catch block.

enter image description here

0

There are 0 best solutions below