JS try/catch문에서 404에러 핸들링

최봉수·2022년 1월 26일
1

api를 연동해서 데이터는 받아오는 함수가 있는데 요청시간 초과, 호출횟수 초과, 응답실패 등등 최대한 보수적인 코드를 짜야했지만, 나는 보수적이지 못했다.

처음엔 아예 에러처리를 안해놨다가, 그 후 에러처리를 해놓긴 했는데 테스트 도중 fetch에 api주소 자체를 날려버려도 콘솔에 처리해둔 에러가 찍히고 api를 받아와서 return해줘야 하는 값은 설정해논 default값으로 제대로 나오길래 그냥 넘어갔었는데, 이번에 테스트 하다가 404에러를 catch하지 못하는 걸 발견했다.

그리하여 구글링과 stackoverflow를 뒤져본 결과 해결한 에러 핸들링을 포스팅한다.

말이 많아서 서론이 깁니다. 그래서 어떻게 했는데? 하시는 분은 맨 아래 '현재 최종 코드' 부분만 확인 하시면 됩니다.

초기 코드

// get api
async function getApi(type) {
    const { lat, lon } = await getGeoLocation();
    const key = 'aaaaaaaaaaaaaaaaaaa';
    const url = `https://aaa/bbbbbb/cccc/d/2.5/${type}?lat=${lat}&lon=${lon}&appid=${key}&units=metric`;
    const response = await fetch(url);
    if (response.ok) return await response.json();
}

위 코드는 완전 초기에 짰던 코드이다.

응답헤더가 ok되면(200등) 결과 값을 return 해주도록 짰었다.
지금보면 왜 그랬는지 이해가 안가지만, 예외 처리를 하나도 하지 않았다.. 그저 성공하면 리턴. 끝

그래서 예외처리를 해주었다

중간 코드

// get api
async function getApi(type) {
    const { lat, lon } = await getGeoLocation();
    const key = 'aaaaaaaaaaaaaaaaaaa';
    const url = `https://aaa/bbbbbb/cccc/d/2.5/${type}?lat=${lat}&lon=${lon}&appid=${key}&units=metric`;
    const response = await fetch(url).catch((err) => console.log(err));
    try {
        return await response.json();
    } catch (err) {
        console.log(err);
    }
}

참으로 이상한 코드가 중간에 나왔었다.
왜 이렇게 짰었지?

이때는 그냥 api주소에 오타를 내서 테스트 해봤는데 에러는 찍히지만 설정해논 default값으로 잘 나왔었다.

하지만, 내가 생각해도 굳이 catch를 두번 쓸 필요가 있을까? 했지만 다른걸 우선 처리해야 했기에 나중에 리팩토링 하자 생각하면서 간단히 주석처리 후 넘어갔다

최종 직전 코드

// get api
async function getApi(type) {
    const { lat, lon } = await getGeoLocation();
    const key = 'aaaaaaaaaaaaaaaaaaa';
    const url = `https://aaa/bbbbbb/cccc/d/2.5/${type}?lat=${lat}&lon=${lon}&appid=${key}&units=metric`;
    try {
        const response = await fetch(url);
        return await response.json();
    } catch (err) {
        console.log(err);
    }
}

fetch 자체를 try안에 넣어서 중복된 catch를 줄였다.
하지만 그래도 여전히 위에 중간코드 부분의

이때는 그냥 api주소에 오타를 내서 테스트 해봤는데 에러는 찍히지만 설정해논 default값으로 잘 나왔었다.

테스트는 잘 나왔다. 404를 발견하기 전까진 이대로 뒀었다.

현재 최종 코드

(최종 코드같은건 없다고 생각한다... 한달후에 내가 보면 또 마음에 안드는 부분이 있을지도.. 아무튼)

// get api
async function getApi(type) {
    const { lat, lon } = await getGeoLocation();
    const key = 'aaaaaaaaaaaaaaaaaaa';
    const url = `https://aaa/bbbbbb/cccc/d/2.5/${type}?lat=${lat}&lon=${lon}&appid=${key}&units=metric`;
    try {
        const response = await fetch(url);
        if (!response.ok) throw new Error('Request faild');
        return await response.json();
    } catch (err) {
        console.log(err);
    }
}

중간에

if (!response.ok) throw new Error('Request faild');

가 추가되었다.

이유

  • typeError로만 거부되어 .catch에 걸리지 않는다. 라는 글을 발견하였다.
  • 이를 해결하려면 직접 에러를 핸들링 해야한다고 한다.

그래서 찾아본 결과 res.ok 필드를 확인하면 http 통신에 에러가 발생하였을 경우 직접 에러를 핸들링할 수 있다고 한다.

그리하여 최종 직전 코드에 try안에서 fetch후 return하기 전에 찾아 봤던 response.ok필드를 확인하여, ok상태가 아니면 에러 처리를 하도록 하였다.

그 결과 api key값을 이상하게 넣어도, url자체를 빈 문자열로 전달 하여도, url에 type파라미터를 이상하게 전달하여도 콘솔엔 처리해논 에러가 찍히고 설정해논 default값이 정상 출력되는 것을 확인하였다.

profile
돈이 좋아

0개의 댓글