Почему внешний try/catch не ловит ошибку, брошенную внутри Promise

Promise сам перехватывает синхронное исключение executor и превращает его в отклонение. Наружу из конструктора это исключение не выходит, поэтому внешний catch не срабатывает.

Короткий ответ

Что ответить на собеседовании

Promise сам перехватывает синхронное исключение executor и превращает его в отклонение. Наружу из конструктора это исключение не выходит, поэтому внешний catch не срабатывает.

Подробный разбор

Ответ с пояснениями

Условие

Разъясните, почему исключение, возникшее внутри тела Promise, не перехватывается внешним блоком try/catch.

try {
  new Promise((resolve, reject) => {
    throw "asda";
  });
} catch (e) {
  console.log("Error", e);
}
  • Внутри конструктора Promise любые синхронные ошибки автоматически преобразуются в отклонённый промис, а не пробрасываются наружу как обычные исключения.
  • Блок try/catch может отловить только ошибки, которые выбрасываются синхронно в текущем стеке вызовов. Ошибка, превратившаяся в отклонение промиса, будет обработана только через методы .catch, await с try/catch внутри асинхронной функции или обработчик отклонения при создании промиса.
  • Чтобы перехватить такую ошибку, нужно добавить обработчик отклонения:
new Promise((resolve, reject) => {
  throw "asda";
}).catch(err => console.log("Caught", err));

или использовать async/await:

(async () => {
  try {
    await new Promise((resolve, reject) => {
      throw "asda";
    });
  } catch (e) {
    console.log("Caught", e);
  }
})();

Ответ

Promise сам перехватывает синхронное исключение executor и превращает его в отклонение. Наружу из конструктора это исключение не выходит, поэтому внешний catch не срабатывает.

Это не потому, что executor асинхронный: он выполняется сразу. Изменяется способ передачи ошибки — через состояние Promise. Добавьте .catch(...) либо await внутри try/catch async-функции, как показано в условии. Без обработчика среда сообщит о необработанном отклонении. Лучше бросать Error вместо строки, чтобы сохранить сообщение и стек; исключение из отдельного timer-callback уже не перехватывается конструктором автоматически.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее