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');
가 추가되었다.
이유
그래서 찾아본 결과 res.ok 필드를 확인하면 http 통신에 에러가 발생하였을 경우 직접 에러를 핸들링할 수 있다고 한다.
그리하여 최종 직전 코드에 try안에서 fetch후 return하기 전에 찾아 봤던 response.ok필드를 확인하여, ok상태가 아니면 에러 처리를 하도록 하였다.
그 결과 api key값을 이상하게 넣어도, url자체를 빈 문자열로 전달 하여도, url에 type파라미터를 이상하게 전달하여도 콘솔엔 처리해논 에러가 찍히고 설정해논 default값이 정상 출력되는 것을 확인하였다.