Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Типи помилок у JavaScript». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**У JavaScript є один базовий клас `Error` і сім вбудованих нащадків: `ReferenceError`, `TypeError`, `RangeError`, `SyntaxError`, `URIError`, `EvalError` та `AggregateError`.** `ReferenceError` виникає на звертанні до неоголошеної змінної, `TypeError` на операції над значенням невідповідного типу або виклику того, що не є функцією, `RangeError` на значенні поза допустимим діапазоном, `SyntaxError` на зламаному синтаксисі (його не спіймати через `try...catch`, бо він стається ще до виконання), `URIError` на некоректних даних у функціях кодування URI, `EvalError` майже не трапляється в сучасних рушіях, а `AggregateError` збирає кілька помилок одразу, наприклад у `Promise.any()`. Будь-який об'єкт помилки має `name`, `message` і `stack`, а власний тип створюють через `class ValidationError extends Error`. **Ключове:** усі помилки успадковуються від `Error`, тому вибір конкретного класу, це спосіб точно сказати, що саме пішло не так.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**У JavaScript усі помилки успадковуються від базового класу `Error`, а вбудованих спеціалізованих типів сім: `ReferenceError`, `TypeError`, `RangeError`, `SyntaxError`, `URIError`, `EvalError` і `AggregateError`.** Кожен із них сигналізує про свій клас проблем, і на додачу ви завжди можете створити власний тип помилки, успадкувавшись від `Error`. ## Теорія ### TL;DR - `Error` це базовий клас із властивостями `name`, `message` і `stack`. - `ReferenceError`, `TypeError` і `RangeError` це три найчастіші помилки часу виконання. - `SyntaxError` виникає на етапі парсингу, тому звичайним `try...catch` його не спіймати. - `URIError` стосується функцій кодування URI, `EvalError` практично не використовується. - `AggregateError` збирає кілька помилок одразу, наприклад у `Promise.any()`. - Власний тип помилки створюють через `class MyError extends Error`. ### Швидкий приклад ```javascript try { null.toString(); } catch (e) { console.log(e.name); // TypeError console.log(e.message); // Cannot read properties of null } ``` ### Error, базовий клас помилок Це **універсальний тип**, від якого успадковуються всі інші помилки. Якщо ви не знаєте, який тип помилки підходить, можна використати просто `Error`. ```javascript throw new Error("Something went wrong"); ``` Властивості об'єкта помилки: - `name`, ім'я помилки (`"Error"`) - `message`, опис - `stack`, трасування стека, показує, де саме сталася помилка ### Помилки часу виконання: ReferenceError, TypeError, RangeError **`ReferenceError`, помилка посилання.** Виникає, коли відбувається **звертання до неіснуючої змінної** або до властивості, недоступної в поточній області видимості. ```javascript console.log(x); // ReferenceError: x is not defined ``` Також може виникати при **неправильному використанні `this`**. **`TypeError`, помилка типу.** Стається, коли операцію застосовують до **значення невідповідного типу** або намагаються викликати те, що не є функцією. ```javascript let n = null; console.log(n.toString()); // TypeError: Cannot read properties of null ``` ```javascript let func = 123; func(); // TypeError: func is not a function ``` **`RangeError`, вихід за допустимі межі.** Виникає, коли передане значення **поза допустимим діапазоном**. ```javascript new Array(-5); // RangeError: Invalid array length ``` ```javascript (123.456).toFixed(200); // RangeError: toFixed() digits argument must be between 0 and 100 ``` ### SyntaxError, URIError, EvalError і AggregateError **`SyntaxError`, синтаксична помилка.** Помилка при **порушенні синтаксису JavaScript**. Рушій не може розібрати код, тому програма **навіть не запускається**. ```javascript eval("if (true { console.log('hi'); }"); // SyntaxError: Unexpected token '{' ``` > Такі помилки не можна спіймати через `try...catch`, бо вони стаються **до початку виконання**. Виняток, це код, який парситься окремо і пізніше, як у прикладі з `eval` вище або у `new Function(...)`. **`URIError`, помилка в URI-функціях.** Стається, якщо функції `encodeURI()`, `decodeURI()`, `encodeURIComponent()` або `decodeURIComponent()` отримують некоректні дані. ```javascript decodeURIComponent("%"); // URIError: URI malformed ``` **`EvalError`, помилка при використанні `eval()`.** У сучасних реалізаціях трапляється рідко. Спочатку її використовували, коли `eval()` застосовували некоректно. ```javascript throw new EvalError("Incorrect use of eval()"); ``` **`AggregateError`, набір помилок.** Виникає, коли **одна операція повертає одразу кілька помилок**, наприклад при `Promise.any()`. ```javascript Promise.any([ Promise.reject(new Error("Error 1")), Promise.reject(new Error("Error 2")), ]).catch(e => console.log(e.errors)); ``` Вивід: ```text [Error: Error 1, Error: Error 2] ``` ### Власні помилки (Custom Errors) Можна створювати власні класи помилок, успадковуючись від `Error`: ```javascript class ValidationError extends Error { constructor(message) { super(message); this.name = "ValidationError"; } } throw new ValidationError("Invalid email"); ``` Вивід: ```text ValidationError: Invalid email ``` Такий підхід дає змогу відрізняти доменні помилки від технічних прямо в `catch`, через `if (e instanceof ValidationError)`. ### Підсумкова таблиця | Тип помилки | Коли виникає | Приклад | | --- | --- | --- | | **Error** | Базовий клас для всіх помилок | `throw new Error("Failure")` | | **ReferenceError** | Змінна не визначена | `console.log(x)` | | **TypeError** | Невірний тип значення | `null.toString()` | | **RangeError** | Значення поза допустимим діапазоном | `new Array(-1)` | | **SyntaxError** | Помилка в синтаксисі | `eval("if (true {")` | | **URIError** | Помилка кодування чи декодування URI | `decodeURI("%")` | | **EvalError** | Помилка `eval()` (майже не використовується) | `throw new EvalError()` | | **AggregateError** | Кілька помилок одразу | `Promise.any([...])` | ### Типові помилки - **Очікувати, що `try...catch` спіймає `SyntaxError` у власному файлі.** Такий код не виконається взагалі, бо розбір відбувається раніше за виконання. - **Ловити все одним `catch (e)` і не дивитися на `e.name`.** Без перевірки типу ви обробляєте помилку валідації так само, як збій мережі. - **Забувати `super(message)` у власному класі помилки.** Тоді `message` буде порожнім, а стек, неповним. - **Плутати `ReferenceError` і `TypeError`.** Змінної немає взагалі, це `ReferenceError`; змінна є, але її значення `null` чи `undefined`, це вже `TypeError`. - **Покладатися на `EvalError`.** Сучасні рушії його майже не кидають, тому будувати логіку навколо нього не варто.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.