Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Конструкція try...catch». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`try...catch` перехоплює помилку часу виконання: код у блоці `try` виконується рядок за рядком, і щойно в ньому виникає виняток, виконання `try` обривається, а керування переходить до `catch`, куди передається об'єкт помилки.** Якщо помилки не було, блок `catch` просто пропускається. Після `try...catch` програма продовжує працювати далі, тому скрипт не «падає», а реагує на збій контрольовано: показує повідомлення, повторює дію, пише лог. ```javascript try { JSON.parse("not valid json"); } catch (error) { console.log("Спіймали:", error.message); } ``` **Ключове:** `try...catch` ловить лише runtime-помилки синхронного коду всередині свого блоку, а необов'язковий `finally` виконується завжди, незалежно від того, була помилка чи ні.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`try...catch` це конструкція обробки винятків: усе, що може зламатися, кладуть у блок `try`, а реакцію на поломку в блок `catch`.** Замість того щоб зупинити весь скрипт, движок передає керування в `catch` разом з об'єктом помилки, і програма продовжує працювати. ## Теорія ### TL;DR - `try` містить код, у якому можлива помилка, `catch (error)` отримує об'єкт помилки й обробляє її. - Якщо помилки немає, блок `catch` пропускається повністю. - Рядки в `try` після місця помилки не виконуються, а код після всієї конструкції виконується далі. - Необов'язковий `finally` спрацьовує завжди: і після успіху, і після помилки. - `throw` дозволяє згенерувати виняток вручну, і його ловить той самий `catch`. - Ловляться лише runtime-помилки синхронного коду всередині блоку. ### Швидкий приклад ```javascript try { // код, у якому може статися помилка JSON.parse("not valid json"); } catch (error) { // виконається, лише якщо помилка виникла console.log("Спіймали:", error.message); } ``` Синтаксис у загальному вигляді: ```javascript try { // код, у якому може статися помилка } catch (error) { // код, який виконається, якщо помилка виникла } ``` ### Як це працює 1. Код у блоці `try` виконується рядок за рядком. 2. Якщо всередині `try` виникає помилка, виконання `try` обривається, і керування передається в `catch`. 3. Якщо помилок немає, блок `catch` пропускається. 4. Після `try...catch` програма продовжує виконання далі. Приклад 1. Без `try...catch` скрипт падає: ```javascript console.log("Початок"); JSON.parse("not valid json"); // SyntaxError console.log("Кінець"); // не виконається ``` Вивід: ```text Uncaught SyntaxError: Unexpected token 'o', "not valid json" is not valid JSON ``` Приклад 2. З `try...catch` програма працює далі: ```javascript console.log("Початок"); try { JSON.parse("not valid json"); } catch (err) { console.log("Помилку спіймано:", err.message); } console.log("Кінець"); ``` Вивід: ```text Початок Помилку спіймано: Unexpected token 'o', "not valid json" is not valid JSON Кінець ``` Помилка оброблена, скрипт не впав. ### Блок finally До конструкції можна додати третій блок, `finally`. Він виконується завжди, незалежно від того, була помилка чи ні. ```javascript try { console.log("Виконуємо try"); throw new Error("Помилка!"); } catch (err) { console.log("Спіймали:", err.message); } finally { console.log("Цей код виконається в будь-якому разі"); } ``` Вивід: ```text Виконуємо try Спіймали: Помилка! Цей код виконається в будь-якому разі ``` > Найчастіше `finally` використовують для прибирання ресурсів: закрити з'єднання, зупинити таймер, видалити тимчасові файли, зняти стан завантаження в інтерфейсі. Якщо змінна помилки не потрібна, з ES2019 її можна не оголошувати взагалі: ```javascript try { JSON.parse(raw); } catch { // сам факт помилки важливіший за її текст return null; } ``` ### Ручний виняток через throw `try...catch` часто застосовують разом з оператором `throw`, щоб згенерувати виняток самостійно: ```javascript function divide(a, b) { if (b === 0) throw new Error("Ділення на нуль!"); return a / b; } try { console.log(divide(10, 0)); } catch (e) { console.log("Помилка:", e.message); } ``` Кидати можна будь-яке значення, але на практиці кидають об'єкт `Error` або його нащадка: тоді є `name`, `message` і `stack`, а `instanceof` дозволяє відрізняти типи помилок у `catch`. ### Особливості поведінки та вкладені блоки | Поведінка | Опис | | --- | --- | | `catch` ловить лише runtime-помилки | Синтаксичні помилки самого скрипта (`SyntaxError` на етапі парсингу) не перехоплюються | | Помилка всередині `catch` не ловиться тим самим `try` | Її треба загорнути в другий `try...catch` | | `try...catch` може бути вкладеним | Різні типи помилок обробляються на різних рівнях | Приклад 3. Вкладені `try...catch`: ```javascript try { try { throw new TypeError("Невірний тип"); } catch (e) { console.log("Внутрішній catch:", e.message); throw new Error("Нова помилка"); } } catch (e) { console.log("Зовнішній catch:", e.message); } ``` Вивід: ```text Внутрішній catch: Невірний тип Зовнішній catch: Нова помилка ``` ### Підсумкова таблиця елементів | Елемент | Призначення | | --- | --- | | `try` | Код, де можлива помилка | | `catch` | Обробляє помилку, якщо вона виникла | | `error` | Змінна, у якій зберігається об'єкт помилки | | `finally` | Виконується завжди, після `try` і `catch` | | `throw` | Генерує виняток, який ловить `catch` | ### Типові помилки - **Чекати, що `try...catch` спіймає помилку з асинхронного колбека.** Виняток усередині `setTimeout` або обробника події виникає вже в іншому такті event loop, коли блок `try` давно завершився. Обробляти треба всередині самого колбека. - **Забувати про `await`.** `try { doAsync(); } catch {}` нічого не спіймає, бо функція лише повертає promise. Потрібен `try { await doAsync(); } catch {}` або `.catch()` у ланцюжку promise. - **Порожній `catch`.** Мовчазне поглинання помилки ховає баг: як мінімум логуйте `error` або кидайте далі. - **Загортати в `try` пів файлу.** Чим більший блок, тим важче зрозуміти, що саме зламалося, і тим легше випадково проковтнути стороннє падіння. - **`return` у `finally`.** Він перекриває значення, повернуте з `try` або `catch`, і навіть «гасить» кинуту помилку, тому так робити не варто. - **Розраховувати на `try...catch` проти синтаксичних помилок.** Скрипт з битим синтаксисом не запуститься взагалі, ловити там нічого.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.