catch
method이전 글에서 promise
객체에 대해 설명할 때, 아래와 같이, then
method의 두 번째 파라미터를 넣어줌으로써, promise
객체가 rejected
상태가 되었을 때 실행할 콜백을 등록할 수 있다고 했었다.
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.text(), (error) => {console.log(error)};)
.then((result) => {console.log(result);})
위 코드를, catch
method를 사용하여 표현해보면 다음과 같다.
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.text())
.catch((error) => {console.log(error);})
.then((result) => {console.log(result);})
사실, 아래 두 코드는 동일한 코드이다.
.catch((error) => {console.log(error);})
.then((undefined, (error) => {console.log(error);}))
다시 말하면, catch
method는, then
method의 첫 번째 파라미터로 undefined
를 넣고, 두 번째 파라미터로 콜백 함수를 넣은 것과 동일하다.
💡
catch
method는then
method를 살짝 변형한 것이라는 사실을 기억해두자.
그렇다면, 아래 코드를 출력하면 어떤 결과가 나올까?
// Internet Disconnected
fetch('https://jsonplaceholder.typicode.com/users') // Promise-A
.then((response) => response.text()) // Promise-B
.then(undefined, (error) => { console.log(error); }) // Promise-C
.then((result) => { console.log(`Quiz: ${result}`); }) // Promise-D
catch
함수는 사실 상 then
method라고 볼 수 있기 때문에, catch
method에서 어떠한 값도 리턴하지 않았으니, undefined
를 리턴한 것으로 간주되어 promise
객체가 fulfilled
상태가 되고, 작업 성공 결과로 undefined
를 갖게 될 것이다. 이로 인해, then
method의 result
파라미터로 undefined
가 넘어갔기 때문에, 최종적으로 undefined
가 콘솔에 출력된 것이다.
이 부분이 이해가 되지 않는다면, Promise Chaining 관련 글을 읽고 오는 것을 추천한다.
catch
아래와 같이 코드를 작성할 경우, 한 가지 문제점이 발생한다.
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.text())
.catch((error) => {console.log(error);})
.then((result) => {
console.log(result);
throw new Error('test');
})
바로, 마지막 줄의 then
method에서 에러가 발생할 경우, 이를 받아서 처리해 줄 두 번째 파라미터가 등록되어 있지 않기 때문에, promise
객체의 상태가 rejected
로 계속 남게되고, 웹 브라우저는 이를 에러로 인식하게 된다는 것이다.
이를 해결하는 방법은 생각보다 간단한데, 아래와 같이, catch
method를 가장 아래로 내려주기만 하면 된다.
fetch('https://jsonplaceholder.typicode.com/users')
.then((response) => response.text())
.then((result) => {
console.log(result);
throw new Error('test');
})
.catch((error) => {console.log(error);})
다만, 중간에 에러가 발생하더라도 catch
method가 그 대안을 뒤로 넘겨줄 수 있는 경우에는, catch
method를 중간에 사용하기도 한다.
아래 예시와 같이, Promise Chain 중에서 에러는 발생했지만, 실패한 작업 대신 다른 방법을 통해 작업을 정상적으로 끝마칠 수 있다면, catch
method를 중간에 활용하는 것도 좋다.
fetch('https://friendbook.com/my/newsfeeds')
.then((response) => response.json()) // -- A
.then((result) => { // -- B
const feeds = result;
// 피드 데이터 가공...
return processedFeeds;
})
.catch((error) => { // -- C
// 미리 저장해둔 일반 뉴스를 보여주기
const storedGeneralNews = getStoredGeneralNews();
return storedGeneralNews;
})
.then((result) => { /* 화면에 표시 */ }) // -- D
.catch((error) => { /* 에러 로깅 */ }); // -- E