Skip to main content

Як створити помилку вручну

Щоб створити помилку вручну, пишемо throw new Error("текст помилки"). Конструктор створює об'єкт помилки, а оператор throw запускає механізм обробки винятків і шукає найближчий try...catch.

Теорія

TL;DR

  • new Error("текст") створює об'єкт помилки, сам по собі він нічого не перериває.
  • throw кидає цей виняток і перериває виконання поточного блоку.
  • Рушій шукає найближчий try...catch; знайшов, помилка потрапляє туди, не знайшов, програма падає.
  • Крім Error є TypeError, RangeError, ReferenceError, SyntaxError та інші нащадки.
  • Свій тип помилки роблять через class ValidationError extends Error.

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

javascript
try { throw new Error("Something went wrong!"); } catch (err) { console.log("caught:", err.message); }

Вивід:

text
caught: Something went wrong!

Як це працює

  1. new Error("текст") створює об'єкт помилки з полями name, message і stack.
  2. throw кидає (генерує) цей виняток.
  3. JavaScript перериває виконання поточного блоку і шукає найближчий try...catch.
  4. Якщо обробник знайдено, помилка «потрапляє» туди. Якщо ні, програма завершується з повідомленням про помилку.

Важливо розділяти два кроки: new Error(...) без throw просто створить об'єкт і нічого не перерве.

javascript
const err = new Error("just an object"); // nothing happens yet throw err; // now the exception is raised

Валідація вхідних даних

Найчастіший сценарій ручного кидання помилки, це перевірка аргументів:

javascript
function divide(a, b) { if (typeof a !== "number" || typeof b !== "number") { throw new TypeError("Arguments must be numbers!"); } if (b === 0) { throw new Error("Division by zero is not allowed!"); } return a / b; } try { console.log(divide(10, 0)); } catch (e) { console.log("Error:", e.message); }

Вивід:

text
Error: Division by zero is not allowed!

Зверніть увагу: для неправильного типу беремо TypeError, для порушеної бізнес-умови, базовий Error.

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

Кидати можна не лише Error, а й його нащадків:

javascript
throw new TypeError("Wrong type"); throw new RangeError("Value is out of range"); throw new ReferenceError("Undefined variable");

Усі вони створюються однаково, через new ...Error("повідомлення"), і всі успадковані від Error, тож instanceof Error для них дає true.

Власний клас помилки

Можна створити свій тип помилки, успадкувавши його від Error:

javascript
class ValidationError extends Error { constructor(message) { super(message); this.name = "ValidationError"; } } function validateUser(user) { if (!user.name) { throw new ValidationError("Name is required!"); } } try { validateUser({}); } catch (e) { console.log(`${e.name}: ${e.message}`); }

Вивід:

text
ValidationError: Name is required!

Окремий клас зручний тим, що в catch його можна відрізнити від інших помилок через instanceof ValidationError і обробити інакше.

Кидати можна будь-що, але краще не треба

Формально throw приймає будь-яке значення:

javascript
throw "an arbitrary string"; throw 404; throw { message: "failure", code: 123 };

Так робити не рекомендується: такі значення не мають ані stack, ані name, ламають звичний формат помилок і роблять код менш передбачуваним. Завжди краще:

javascript
throw new Error("Message");

І пам'ятайте, що throw без обробника зупиняє програму:

javascript
throw new Error("Critical failure!"); console.log("this line never runs");

Вивід:

text
Uncaught Error: Critical failure!

Інструменти в одному місці:

Що використовуємоПризначення
throwКидає виняток
ErrorБазовий клас помилок
TypeError, RangeError, ReferenceErrorСпеціалізовані типи помилок
try...catchОбробляє помилку
class CustomError extends ErrorСтворення власних помилок

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

  • Писати new Error("...") без throw і дивуватися, що виконання йде далі.
  • Кидати рядки або числа замість об'єктів Error, через це в catch немає ні stack, ні name.
  • Забувати super(message) у власному класі помилки, тоді message лишиться порожнім.
  • Не ставити this.name у власному класі, і в логах помилка виглядатиме як звичайний Error.
  • Кидати помилку всередині catch без зовнішнього try...catch, такий виняток уже ніхто не спіймає.

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

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

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