티스토리 뷰

11.4 Error handling with promises

catch는 .then 뒤에 오더라도 상관없다. 

fetch('/article/promise-chaining/user.json')
  .then(response => response.json())
  .then(user => fetch(`https://api.github.com/users/${user.name}`))
  .then(response => response.json())
  .then(githubUser => new Promise((resolve, reject) => {
    let img = document.createElement('img');
    img.src = githubUser.avatar_url;
    img.className = "promise-avatar-example";
    document.body.append(img);

    setTimeout(() => {
      img.remove();
      resolve(githubUser);
    }, 3000);
  }))
  .catch(error => alert(error.message));

Implicit try...catch

프라미스 executor와 프라미스 핸들러 주위에는 보이지 않는 try..catch가 있다. 예외 발생 시 이 try..catch가 동작하여 예외를 잡고 이를 reject처럼 다룬다. 

new Promise((resolve, reject) => {
  throw new Error("에러 발생!");
}).catch(alert); // Error: 에러 발생!

// ----------------
// 위 코드와 똑같이 동작함.
new Promise((resolve, reject) => {
  reject(new Error("에러 발생!"));
}).catch(alert); // Error: 에러 발생!

핸들러에서도 마찬가지다.

new Promise((resolve, reject) => {
  resolve("OK");
}).then((result) => {
  throw new Error("에러 발생!"); // 프라미스가 거부됨
}).catch(alert); // Error: 에러 발생!

Rethrowing

체인 마지막에 .catch 하나만 있으면, .then 핸들러에서 발생한 모든 에러를 처리할 수 있다. 만약 catch안에서 throw를 사용했다면 가장 가까운 .then 핸들러로 넘어가서 실행한다.

// 실행 순서: catch -> then
new Promise((resolve, reject) => {

  throw new Error("에러 발생!");

}).catch(function(error) {

  alert("에러가 잘 처리되었습니다. 정상적으로 실행이 이어집니다.");

}).then(() => alert("다음 핸들러가 실행됩니다."));

// --------------

// 실행 순서: catch -> catch
new Promise((resolve, reject) => {

  throw new Error("에러 발생!");

}).catch(function(error) { // (*)

  if (error instanceof URIError) {
    // 에러 처리
  } else {
    alert("처리할 수 없는 에러");

    throw error; // 에러 다시 던지기
  }

}).then(function() {
  /* 여기는 실행되지 않습니다. */
}).catch(error => { // (**)

  alert(`알 수 없는 에러가 발생함: ${error}`);
  // 반환값이 없음 => 실행이 계속됨

});

Unhandled rejections

아래 예시처럼 에러를 처리하지 못하게 되면 어떻게 될까?

new Promise(function() {
  noSuchFunction(); // 존재하지 않는 함수를 호출하기 때문에 에러가 발생함
})
  .then(() => {
    // 성공상태의 프라미스를 처리하는 핸들러. 한 개 혹은 여러 개가 있을 수 있음
  }); // 끝에 .catch가 없음!

엔진은 전역에러를 생성한다. 콘솔창에서 해당 전역에러를 확인할 수 있다. 

window.addEventListener('unhandledrejection', function(event) {
  // unhandledrejection 이벤트엔 두 개의 특수 프로퍼티가 있습니다.
  alert(event.promise); // [object Promise] - 에러를 생성하는 프라미스
  alert(event.reason); // Error: 에러 발생! - 처리하지 못한 에러 객체
});

new Promise(function() {
  throw new Error("에러 발생!");
}); // 에러를 처리할 수 있는 .catch 핸들러가 없음
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday