promise
가 reject
되면 가장 가까운 에러 핸들러에서 에러를 처리하게 된다.
.catch
는 promise
에서 발생한 모든 에러를 처리한다.
하나 또는 여러개의 .then
뒤에 .catch
를 사용할 수 있다.
fetch('존재하지 않는 주소')
.then(res => res.json())
.catch(err => alert(err)) // TypeError: failed to fetch
promise
는 보이지않는 try...catch
가 에러를 잡고, promise
를 reject
상태로 변경시킨다.
new Promise((resolve, reject) => {
reject(new Error("에러 발생!"));
}).catch(alert); // Error: 에러 발생!
new Promise((resolve, reject) => {
throw new Error("에러 발생!");
}).catch(alert); // Error: 에러 발생!
두 코드는 같은 결과를 출력한다.
new promise((resolve, reject) => {
resolve("ok");
}).then((result) => {
throw new Error("에러 발생!");
}).catch(alert); // Error: 에러 발생!
.then
안에서throw
를 사용해 에러를 던지면,
이 자체가reject promise
를 의미하게 되고,
따라서 가장 가까운 에러 핸들러로 넘어가게 된다.
promise chain
의 마지막 .catch
는 try...catch
와 비슷한 역할을 한다.
.then
을 원하는 만큼 사용하다가 마지막에 .catch
하나를 붙이면 .then
에서 발생한 모든 에러를 처리할 수 있다.
new Promise((resolve, reject) => {
throw new Error("에러 발생!"); // 1.
}).catch(function(error) { // 2.
if(error instanceof URIError) {
// 에러 처리
} else {
alert("처리할 수 없는 에러!");
throw error; // 3.
}
}).then(function() {
// 4.
}).catch(error => { // 5.
alert(`알 수 없는 에러가 발생함: ${error}`);
});
throw
로 인해promise
가reject
상태가 된다..catch
에서 에러 처리를 한다.- 처리할 수 없는 에러라면 다시 에러를 던진다.
- 에러이기 때문에 다음
.then
은 실행되지 않는다.- 다음
.catch
에서 에러를 처리한다.
(여기서 에러가 성공적으로 처리되고 그 다음에.then
이 사용되면 실행이 이어지게 된다.)
에러가 발생 했는데 에러를 처리해줄 코드가 없다면 에러가 갇혀버린다.
스크립트는 중지되고 console
창에 에러 메시지가 출력된다.
promise
의 reject
를 처리하지 못했을 때도 비슷하다.
브라우저 환경에서는 이런 에러를 unhandledrejection
이벤트로 잡을 수 있다.
unhandledrejection
이벤트로 처리되지 않은 에러를 추적하고, 이를 사용자 또는 서버에 알려서 아무런 반응없이 스크립트가 중지되는 걸 방지할 수 있다.