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

column clash·2022년 4월 6일
0

훨씬 나은 방법의 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개의 댓글