http요청을 할 때 오류가 발생할 수 있다.
기술적 오류 예를들어 네트워크 연결이 없다든지
http요청을 하였는데 error 응답을 받은 경우가 그렇다.
이 오류는 404, 500, 401등과 같은 오류다.
오류 종류에 대해서는 나중에 살펴보기로 하자.
대략적으로
403, 401 등은 요청이 성공적으로 전송되었고 기술적 문제가 없었는데 서버가 원하는 요청을 주지 않았음을 의미한다.
기술적으로 성공적으로 응답받았으나 응답에 오류 코드가 포함되어있어 오류 문자를 받은 것이다.
500번대는 서버에러가 발생한 경우다.
만약 api의 URL을 조금 다르게 변경한 경우
404 에러가 발생하게 된다.
이 때는 그냥 Loading 문구에서 넘어가지 않고 계속 멈춰있게 되는데
에러 문구를 띄워 문제가 발생되었음을 사용자에게 알리는 편이 낫다.
error state를 만들고 fetch 함수 안에 넣어준다.
function App() {
const [movies, setMovies] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
function fetchMoviesHandler() {
setIsLoading(true);
setError(null);
그리고 fetch 다음에 .catch 함수를 넣어 에러를 확인한다.
여기서 우리가 직면하게 될 문제는
fetch API는 에러 상태 코드를
실제 에러로 취급하지 않는다는 것이다.
에러상태 코드를 받아도 기술적 에러로 처리되지 않는다.
그래서 문제는 실제 오류로 처리되지 않는다.
우리가 받지 못한 데이터로 어떤 작업을 하려고 할 때만
오류가 발생하게 된다. 이건 우리가 원하는 방식이 아니다.
성공적이지 못한 상태 코드를 받았을 때 에러가 발생하는 것이 좋을 것이다.
그러나 말했듯, 기본적으로 fetch API는 그렇게 하지 않을 것이다.
1. setError(null)로 변경한다
이전에 받았을지도 모르는 error를 null인 상태로 변경하는 것이다.
function fetchMoviesHandler() {
setIsLoading(true);
setError(null);
2. 실제 오류가 발생했을 때 null 이외의 값을 사용한다.
서드파티 라이브러리 패키지 axios는
요청전송에 성공한다면
에러 상태에 맞는 에러를 만들어서 전달한다.
그러나 우리는 axios를 사용하지 않으니 직접 만들어야 한다.
if 문으로 만들어준다.
async function fetchMoviesHandler() {
setIsLoading(true);
setError(null);
try {
const response = await fetch("https://swapi.dev/api/film/");
const data = await response.json();
if (!response.ok) {
throw new Error("Something went wrong!");
}
const transformedMovies = data.results.map(movieData => {
return {
id: movieData.episode_id,
title: movieData.title,
openingText: movieData.opening_crawl,
releaseData: movieData.release_date,
};
});
setMovies(transformedMovies);
setIsLoading(false);
} catch (error) {
setError(error.message);
}
}
만약 오류가 생긴다면 아래의 const transformed 이하의 코드가 실행되지 않을 것이므로
catch문을 만들어 에러를 캐치하여 상태를 관리할 수 있게 해준다.
오류 상태를 관리하고 나면
오류 존재 여부에 따라 렌더링 되는 문구를 정해주어야 한다.
그리고 오류가 발생했기 때문에 더이상의 로딩 작업은 멈춰주어도 된다 .
그러면 이렇게 나오게 된다.
found no movies 문구와 함께
에러문구가 뜨게 되는 것이다.
async function fetchMoviesHandler() {
setIsLoading(true);
setError(null);
try {
const response = await fetch("https://swapi.dev/api/film/");
const data = await response.json();
여기 코드에서
에러문구는 내가 정한것이 아니고
JSON에 대한 응답을 호출했는데 이 구문도 실패한 것이다.
const data = await response.json();
그 위의 줄이 제대로 된 데이터를 받지 못했기 때문이다.
const response = await fetch("https://swapi.dev/api/film/");
그래서 response body부분을 파싱하기 전에 response.ok를 체크해야 한다.
async function fetchMoviesHandler() {
setIsLoading(true);
setError(null);
try {
const response = await fetch("https://swapi.dev/api/film/");
if (!response.ok) {
throw new Error("Something went wrong!");
}
const data = await response.json();
그러면 내가 설정해 준 에러문구가 나오게 된다.
Found no movies는 !error 일때만 뜨는 조건을 넣는다.
그렇기 때문에 지금은 error 상태이므로 뜨지 않게 된다.
에러 응답을 다루는 방법은 어떤 API와 통신하는지에 따라 다르다.
어떤 API는 요청이 성공적이지 못해도 JSON 데이터를 보낸다.
지금과 같은 API는 JSON 데이터를 보내지 않는다.
따라서 response body부분을 파싱하기 전에 response.ok를 체크하도록 위치를 바꾸어 주는 것이 좋다.