Skip to main content

Оператор throw

Оператор throw використовують для створення і викидання помилки, тобто для примусового переривання виконання коду та передачі керування в найближчий блок catch, якщо він є. Це основний спосіб повідомити про ситуацію, з якою функція не може коректно впоратися.

Теорія

TL;DR

  • throw вираз; негайно припиняє виконання поточної функції.
  • Далі JavaScript шукає найближчий try...catch, щоб спіймати це значення.
  • Кинути можна будь-яке значення: рядок, число, об'єкт. Але правильний вибір це Error або його підклас.
  • Підкласи TypeError, ReferenceError, SyntaxError, RangeError, EvalError уточнюють природу проблеми.
  • Блок finally виконується завжди, незалежно від того, чи була помилка.

Швидкий приклад

javascript
throw new Error("Щось пішло не так!");

Коли інтерпретатор зустрічає throw, виконання поточної функції негайно припиняється, і JavaScript починає шукати найближчий блок try...catch, щоб спіймати цю помилку. Якщо такого блоку немає, помилка доходить до верху стека і програма (або поточна задача) падає.

Синтаксис і що саме можна кидати

javascript
throw вираз;

Де вираз це будь-яке значення, але найчастіше це об'єкт помилки (Error).

Обробка через try...catch:

javascript
try { throw new Error("Помилка з'єднання з сервером!"); } catch (error) { console.log("Спіймали помилку:", error.message); }

Результат:

Спіймали помилку: Помилка з'єднання з сервером!

JavaScript не вимагає викидати саме об'єкт помилки, кинути можна що завгодно:

javascript
throw "Просто рядок"; throw 404; throw { message: "Помилка даних", code: 123 };

Але за стандартом краще завжди використовувати Error або його підкласи: лише вони гарантовано мають name, message і стек викликів.

Вбудовані типи помилок

  • Error це базовий тип
  • TypeError
  • ReferenceError
  • SyntaxError
  • RangeError
  • EvalError

Приклад з конкретним типом:

javascript
function divide(a, b) { if (b === 0) { throw new RangeError("Ділення на нуль!"); } return a / b; } try { divide(5, 0); } catch (err) { console.error(err.name + ": " + err.message); }

Результат:

RangeError: Ділення на нуль!

Обраний тип помилки дозволяє в catch розрізняти ситуації через err instanceof RangeError і реагувати по-різному.

Як це працює у зв'язці try...catch...finally

javascript
try { console.log("Починаємо"); throw new Error("Помилка!"); } catch (e) { console.log("Спіймали:", e.message); } finally { console.log("Цей блок виконається завжди"); }

Результат:

Починаємо Спіймали: Помилка! Цей блок виконається завжди

Підсумкова таблиця:

Що робитьОпис
throwПерериває виконання і викидає помилку
Що можна викинутиБудь-яке значення (але рекомендований Error)
Чим обробляєтьсяtry...catch
Після throwКод у тому самому блоці не виконується
Блок finallyВиконується завжди, навіть за throw

Типові помилки

  • Кидати рядок замість Error. У catch тоді немає ні message, ні stack, а логи стають марними. Пишіть throw new Error("...").
  • Забувати new. throw Error("...") теж працює, бо Error можна викликати без new, а от власний клас помилки без new поводитиметься не так, як очікується.
  • Очікувати, що код після throw виконається. Решта інструкцій у тому самому блоці недосяжна.
  • Ковтати помилку порожнім catch. Блок catch (e) {} приховує проблему; або обробіть її, або киньте далі через throw e.
  • Ставити return у finally. Він перекриє і значення, що поверталося, і помилку, яку кидали, тож проблема тихо зникне.
  • Розраховувати, що try...catch спіймає асинхронну помилку. Викид усередині setTimeout або в необробленому промісі поза цим блоком не ловиться: для промісів потрібні await у try або .catch().

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.