가장 기초적인 에러핸들링 (with 리액트쿼리)

column clash·2022년 4월 6일

훨씬 나은 방법의 error 핸들링이 존재하고
밑에 내용은 너무나 기초적인 임시적인 error 핸들링이라
적기도 무안하지만, 그래도 기초적으로 에러핸들링을
하는 방법을 적어놓은다.

에러를 나타나는 메세지들은,
https://yamoo9.github.io/axios/guide/error-handling.html

if (error.response) {
// 요청이 이루어졌으며 서버가 2xx의 범위를 벗어나는 상태 코드로 응답했습니다.
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
}
else if (error.request) {
// 요청이 이루어 졌으나 응답을 받지 못했습니다.
// error.request는 브라우저의 XMLHttpRequest 인스턴스 또는
// Node.js의 http.ClientRequest 인스턴스입니다.
console.log(error.request);
}
else {
// 오류를 발생시킨 요청을 설정하는 중에 문제가 발생했습니다.
console.log('Error', error.message);
}
console.log(error.config);

가 있다.

보통 error.response?.data.message 를 적어보면, mongodb 기준
mongodb 가 알려주는 에러이유들이 나옴,


// back-end

boardRouter.get(async (req: NextApiRequest, res: NextApiResponse) => {
  try {
    const { _id } = req.query;
    if (!mongoose.Types.ObjectId.isValid(String(_id))) {
      return res.status(400).send({ err: "id형식에 맞지 않습니다." });
    }

    if ((await Board.find({ _id }).countDocuments()) === 0) {
      return res.status(404).send({ err: "잘 못된 경로로 접속하셨습니다." });
    }

    const users = await User.find({}).limit(1);
    const boards = await Board.find({ _id }).populate("userid", "nickname");
    return res.send(boards);
  } catch (err) {
    console.log(`message : ${err}`);
    res.status(500).send({ err: (err as Error)?.message });
  }
});

에러가 날만한 상황에 대해서, 미리 에러를 리턴해주도록 해준다.

// front

// 게시물 리스트 가져오기
  const { status, data, error } = useBoardDetail(String(_id));

  //에러핸들링
  useEffect(() => {
    if (status === "error") {
      toast.error("올바른 경로로 접속해주세요", {
        position: "top-right",
        autoClose: 2000
      });
      setTimeout(() => router.push("/answer"), 2000);
    }
  }, [router, status]);

// react query

const useBoardDetail = (_id: string) => {
  return useQuery<IBoard, AxiosError>(
    ["detailBoardData", _id],
    async () => await fetchBoard(_id)
  );
};

이 경우에, error.response?.data.err  에
'never' 형식에 'err' 속성이 없습니다.

const useBoardDetail = (_id: string) => {
  return useQuery<IBoard, AxiosError<{ err: string }>>(
    ["detailBoardData", _id],
    async () => await fetchBoard(_id)
  );
};

이렇게 <T> 에 들어갈 것을 적어주면 해결된다.

// 콘솔에 정확하게 이유를 찍고 싶다면,
//에러 처리, 정확한 메세지

  console.log("error data", status === "error" && error.response?.data.err);

사용자에게 굳이 서버에서 보내지는 메세지를 알려줄 필요는 없을 것이다.
라고 하면 된다.

예를 들어

CastError: Cast to ObjectId failed for value "624dc8471a41365fb4e4751111" (type string) at path "_id" for model "Board"1111

이렇게 사용자에게 서버 날것의 오류를 보여줄리는 없고, 이건 개발자가 보면 될 것이고, 실제 프러덕션에서는 여러 에러 상황을 상정해서 적당한 메세지와 액션이 일어나도록 하면 될 것이다.

에러핸들링에 대해서도 전체적인 학습이 필요한 시점인 것 같다.

profile
풀스택 개발 중...

0개의 댓글