본문 바로가기
CS 질문

[Deep Dive CS- Q7, Q8, Q9] setTimeout, await/async, promise 에서의 에러 처리

by 민챙이_99 2025. 12. 15.

Q7. 아래 코드의 결과를 예상하고 이유를 설명해주세요

try {
  setTimeout(() => {
    throw new Error('잡아봐라!'); // 에러 발생!
  }, 1000);
} catch (e) {
  console.log('잡았다!', e);
}

 

- 결과 : 자바 스크립트 에러가 발생하게 된다. catch문은 실행되지 않는다. 

왜냐하면, 콜스택에 try-catch가 들어갔다. 그리고 거기에서 setTimeout을 Web API에게 할당한다. Web API는 1초를 기다린 뒤 콜백 함수를 Task Queue에 담는다(단순 전달만 함). 이후 콜 스택으로 옮겨져 실행되는 순간 오류가 발생한다. 하지만 이때 try-catch는 이미 사라지고 없다. 그래서 error는 window.onerror까지 올라가게 된다. 

 

 

Q8 아래 코드의 결과를 예상하고 이유를 설명해주세요

async function errorTest() {
  try {
    // await는 Promise가 끝날 때까지 "함수의 실행을 일시 정지" 시킵니다.
    // 즉, 아직 스택(논리적인 문맥)이 살아있는 상태로 기다립니다.
    await new Promise((resolve, reject) => {
      setTimeout(() => reject(new Error('이건 잡힌다!')), 1000);
    });
  } catch (e) {
    console.log('잡았다!', e); // 성공!
  }
}
  • await는 내부적으로 Generator를 사용하여 함수의 실행 컨텍스트를 유지 합니다.
  • 마이크로태스크 큐에서 에러(Reject)가 넘어올때, 엔진은 멈춰 있던 try 블록 내부로 다시 진입해서 에러를 던져 줍니다

 

 

Q9. 아래 코드의 결과를 예상하고 이유를 설명해주세요

try {
  new Promise(() => {
    throw new Error('Promise 내부 에러');
  });
} catch (e) {
  console.log('이것도 못 잡습니다.');
}

 

  • Promise 내부에서 발생한 에러는 try-catch로도 못잡고, 일반적인 window.onerror로도 안잡히는 경우가 있습니다. 
    이를 에러 먹힘(Error Swallowing)이라고 합니다. 
  • Promise 내부의 에러는 throw가 아니라 reject()로 취급됩니다. 즉, 예외가 아니라 "실패 상태"가 되는 것입니다. 
  • 그래서 .catch()를 체이닝하거나, 전역 이벤트인 unhandledrejection 이벤트를 리스닝 해야 합니다.

 

+ Deep dive

Q. 다음 코드에서 catch 블록에 잡히는 에러는 무엇이고, window.onerror (전역 에러 핸들러)로 빠져나가는 에러는 무엇일까요?

try {
  // 1. 동기 에러
  // throw new Error('Error 1'); 

  // 2. Promise 에러 (await 없음)
  Promise.resolve().then(() => {
    throw new Error('Error 2');
  });

  // 3. 비동기 함수 내부 에러
  (async () => {
    throw new Error('Error 3');
  })();

} catch (e) {
  console.log('Caught:', e.message);
}

 

  • 결론 : 아무것도 잡지 못함.
  • Async 함수의 리턴값은 무조건 Promise : async 함수 내부에서 await 없이 throw new Error()를 하면, 이는 일반적인 예외 발생이 아니라, Rejected Promise(실패한 상태)를 리턴하는 행위로 변환됩니다. 
  • 받아줄 await이나 .catch가 없으므로 전역(Unhandled Rejection)으로 날아갑니다.