소프트웨어 엔지니어링/프론트 엔드

Axios 사용시 예외처리에서 주의할 점

dhsimpson 2023. 6. 16. 13:03

회사에서 NextJS 프로젝트를 하면서 useEffect hook에서 BFF 에 호출하는 로직을 추가했다.

 

function useAxiosCall<T>(apiUrl: string) {
	const [data, setData] = useState<T | null>(null);
	useEffect(()=>{
    		Axios.get<T>(apiUrl).then(res => {
        		setData(res.data);
	        });
    	}, []);
}

 

해당 axios 호출에서 예외가 발생하는 경우가 있었고, 익숙하듯 try...catch 문으로 감싸줘 봤다.

 

function useAxiosCall<T>(apiUrl: string) {
	const [data, setData] = useState<T | null>(null);

	useEffect(()=>{
            try{
                Axios.get<T>(apiUrl).then(res => {
                    setData(res.data);
                });
            }catch(e){
            	/** 에러처리 로직 */
            }

    	}, []);
}

 

하지만 try...catch 문은 예외를 catch하지 못 했고, Axios 가 제공하는 Catch 메서드를 이용하니 예외를 잘 catch 했다.

 

function useAxiosCall<T>(apiUrl: string) {
	const [data, setData] = useState<T | null>(null);

	useEffect(()=>{
                Axios.get<T>(apiUrl).then(res => {
                    setData(res.data);
                }).catch((e)=>{/** 에러처리 로직 */});

    	}, []);
}

 

이유가 뭔고 하니...Axios.get 은 비동기 함수이기 때문인데,(이건 누구나 다 아는 사실이지만 간과한 것 같다.)

Axios.get 의 처리는 Web API 에서 하게 되는 동시에 Axios.get 이후 로직이 실행되고(여기선 이후 로직이 없다.) try...catch 문을 벗어난다.

결과적으론, 런타임에선 Axios.get 의 에러 발생 시점이 try...catch 문이 끝난 이후 이기에 위와 같은 현상이 벌어졌던 것이다.

 

해결 방법으론 아래와 같이 Axios.get 에 await 키워드를 적용해 예외가 발생해도 try...catch 문 내에서 발생하도록 동기화를 시켜주는 것이다.

 

function useAxiosCall<T>(apiUrl: string) {
	const [data, setData] = useState<T | null>(null);

	useEffect(()=>{
    	// useEffect 엔 비동기 함수를 Callback 으로 전달할 수 없기에
        // 콜백함수 내에서 비동기 함수를 선언하자 마자 실행하도록 한다.
        // try...catch 로 감싸주는 것 또한 해당 비동기 함수 내에서 한다.
    	(async function callApi(){
            try{
                await Axios.get<T>(apiUrl).then(res => {
                        setData(res.data);
                    });
                // 물론 아래와 같이 해도 결과는 동일하다.
                /**
                const res = await Axios.get<T>(apiUrl);
                setData(res.data);
                */
            }catch(e){
             /** 예외처리 로직 */
            }
        })();
                
    	}, []);
}

 

Javascript의 비동기 처리는 항상 쉽지 않다. (비동기가 기본적인 동작이라..)