React 동적 라우팅에서 임의의 경로에 대한 404 에러를 어떻게 처리하면 좋을까?

JulyK9·2022년 12월 23일
1

문제상황

  • useParams와 URL을 통한 동적 라우팅으로 스터디(잼)의 상세페이지는 구현한 상태였는데, 유저가 입력창에 임의의 숫자(:id)를 입력하는 경우 다음과 같은 상황이 발생된다.

접근방향

  • 데이터가 없는 상태(동적 라우팅의 :id가 없는)의 path를 임의로 입력할 경우 잘못된 페이지에 접근했다는 것을 유저에게 알려주는 방식이 되어야 한다고 생각했다.
  • 잘못된 페이지는 다른 팀원분이 만들어 놓으셨기 때문에 연결만 하면 될텐데..
  • 그렇다면 입력한 임의의 숫자(:id)는 데이터가 없는 경우이므로 데이터 fetching 할 때 서버에서 보내주는 응답에 데이터가 없는 경우를 분기로 잡아 처리해주면 될 것 같다.
  • 다음과 같이 네트워크 부분에서 404가 응답으로 오는 것을 확인할 수 있었고 다른 부분을 구현할 때 바디없이 정상적으로 오는 200 응답의 상태코드를 잡아서 로직을 구현한 적이 있기 때문에, 404 응답을 상태코드로 잡아서 구현하면 된다고 생각했다
  • 데이터를 불러오는 부분 코드
const getJamData = async () => {
    await axios
      .get(`${BASE_URL}/jams/${id}`)
      .then(res => {
        setJamData({ ...res.data });
        setIsComplete({ ...res.data }.completeStatus);
        setJoiner({ ...res.data }.participantList);
    });
  };

2차 문제

  • 404 응답의 상태코드 콘솔로 찍어가며 잡으려고 했으나 도무지 잡히질 않았다.
  • 다른 방법으로는 해당 데이터(id)가 존재하는지에 대해 별도 api로 사전 요청을 보내, 존재여부를 응답받으면서 처리해볼까 생각했으나, 백엔드와의 추가적인 협의가 필요하고 요청을 2번이나 보낸다는 것도 비효율적으로 생각되었다.
  • 결국 404 상태코드를 못잡는 부분에 대한 자료를 더 찾아보게 되었는데, 404 응답 자체가 에러이기 때문에 상태코드로 잡아서 처리할 수 없으며 다음과 같은 방법이 있었다.

해결방법1.

  • axios 옵션 설정으로 404 에러 응답을 특정하여 처리

    axios 를 통한 요청시 { validateStatus: false } 옵션을 설정하면 status에 대한 검증 자체를 하지 않기 때문에 에러를 처리하는 catch 로 넘어가지 않고 try 내부에서 404 에러를 상태코드로 잡아서 처리할 수 있다고 한다

  • 코드 적용 후
const getJamData = async () => {
    await axios
      .get(`${BASE_URL}/jams/${id}`, { validateStatus: false })
      .then(res => {
        if (res.status === 404) {
          navigate('*');
          setTimeout(() => {
            alert('잘못된 접근입니다. 메인페이지로 이동합니다.');
            navigate('/');
          }, 3000);
        } else {
          setJamData({ ...res.data });
          setIsComplete({ ...res.data }.completeStatus);
          setJoiner({ ...res.data }.participantList);
        }
      });
  };

해결방법2.

  • 에러에 대한 처리이므로 try catch 구문의 catch에서 처리

    error의 status로 바로 에러 처리하지 않고 다음과 같이 response 프로퍼티의 status로 처리
    console로 에러 객체를 확인해보면 404를 어떻게 잡아야할지 확인할 수 있었다.

  • error 객체 확인

  • 코드 적용 후

const getJamData = async () => {
	try {
      const res = await axios.get(`${BASE_URL}/jams/${id}`);
      if (res.status === 200) {
        setJamData({ ...res.data });
        setIsComplete({ ...res.data }.completeStatus);
        setJoiner({ ...res.data }.participantList);
      }
    } catch (error) {
      // console.log('error', error); // 에러 객체 확인용
      if (error.response.status === 404) {
        navigate('*');
        setTimeout(() => {
          alert('잘못된 접근입니다. 메인페이지로 이동합니다.');
          navigate('/');
        }, 3000);
      }
    }
  };

처리 결과

  • 해결방법 2가지 모두 잘 적용되어서 처리가 가능했다.
  • 아래와 같이 잘못된 페이지로 연결하여 안내하고 3초후 alert 창으로 재안내후 메인 페이지로 이동시키도록 처리하였다.

회고

  • 네트워크 통신에서 응답 객체를 확인하고 바로 잡아서 처리하는게 중요한 게 아니라
  • 정상적인 응답과 에러라는 것을 각각 어떤 범주로 인지하여 어디에서 어떻게 처리해주어야 하는지을 배운 시간이었다.

참고자료

https://webisfree.com/2022-04-28/[%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8]-axios%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%98%B8%EC%B6%9C%EC%8B%9C-try-catch-%EA%B5%AC%EB%AC%B8%EC%97%90%EC%84%9C-404-%EC%97%90%EB%9F%AC%EC%9D%98-response%EB%A5%BC-%EC%B2%98%EB%A6%AC%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95

profile
느리지만 꾸준하게. 부족하거나 잘못된 부분은 알려주시면 감사하겠습니다.

0개의 댓글