Коли виконується блок catch
catch виконується тільки тоді, коли в блоці try виникло виключення. Помилку могли кинути вручну через throw або її згенерував сам движок, наприклад ReferenceError чи TypeError. Якщо try відпрацював чисто, блок catch пропускається, наче його немає.
Теорія
TL;DR
catchспрацьовує рівно за однієї умови: усередині йогоtryкинуто виключення.- Джерело помилки не має значення: ручний
throwі автоматична помилка движка обробляються однаково. - Помилка обриває
tryна місці, наступні рядки блоку не виконуються. - В
catch(error)доступний об'єкт помилки зname,messageіstack. - Помилка поза блоком
tryне перехоплюється. - Асинхронна помилка з колбека або з promise без
awaitтеж не перехоплюється. - Якщо помилок могло бути кілька, обробляється перша: до другої виконання не дійде.
Швидкий приклад
try {
console.log("Початок");
throw new Error("Сталася помилка!");
console.log("Цей код не виконається");
} catch (error) {
console.log("Спіймали:", error.message);
}Вивід:
Початок
Спіймали: Сталася помилка!Покроковий механізм
- Код усередині
try { ... }починає виконуватися рядок за рядком. - Якщо помилок немає,
catchне викликається взагалі. - Якщо всередині
tryсталася помилка, виконанняtryнегайно обривається і керування переходить уcatch. - У
catch (error)доступний об'єкт помилки, який можна обробити, залогувати або кинути далі.
Коли catch спрацьовує
Приклад 1. Помилки немає, тому catch не спрацьовує:
try {
console.log("Усе працює чудово!");
} catch (error) {
console.log("Спіймали помилку:", error.message);
}
console.log("Продовжуємо виконання...");Вивід:
Усе працює чудово!
Продовжуємо виконання...Приклад 2. Автоматична помилка движка:
try {
console.log(a); // ReferenceError: a is not defined
} catch (error) {
console.log("Спіймали:", error.name); // ReferenceError
}catch спрацьовує тому, що JavaScript сам кинув виключення під час звернення до неоголошеної змінної.
Приклад 3. Помилка обриває try посередині:
try {
console.log("1");
JSON.parse("not valid json"); // помилка тут
console.log("2"); // не виконається
} catch (error) {
console.log("Спіймали:", error.message);
}
console.log("3");Вивід:
1
Спіймали: Unexpected token 'o', "not valid json" is not valid JSON
3Приклад 4. Якщо помилок кілька, обробляється перша:
try {
throw new Error("Помилка 1");
throw new Error("Помилка 2"); // не виконається
} catch (err) {
console.log("Спіймано:", err.message);
}Вивід:
Спіймано: Помилка 1Коли catch не спрацьовує
Помилка, що сталася поза блоком try, не має жодного стосунку до цього catch:
try {
console.log("Усередині try все добре");
} catch (error) {
console.log("Спіймали помилку:", error.message);
}
throw new Error("Помилка поза try!"); // не буде перехопленаСкрипт впаде з неперехопленою помилкою, бо вона виникла після того, як конструкція вже завершилася.
Асинхронний код
try...catch не ловить помилки всередині колбеків і promise, якщо не використати await або .catch().
try {
setTimeout(() => {
throw new Error("Помилка в колбеку"); // не буде спіймана
}, 1000);
} catch (e) {
console.log("Спіймано:", e.message);
}Виклик setTimeout завершується миттєво і без помилки, а сам колбек виконується пізніше, коли блок try уже закрито. Щоб перехоплювати помилки з promise, потрібен async/await або .catch():
async function run() {
try {
await Promise.reject(new Error("Помилка в promise"));
} catch (e) {
console.log("Спіймали:", e.message);
}
}
run();Підсумкова таблиця
| Ситуація | Чи виконається catch | Причина |
|---|---|---|
У try немає помилок | Ні | Код відпрацював нормально |
У try виконано throw | Так | Виключення кинуто всередині блоку |
JavaScript сам кинув помилку (ReferenceError тощо) | Так | Автоматична помилка часу виконання |
Помилка поза try | Ні | Не входить в область обробки |
Помилка в колбеку або promise без await | Ні | Асинхронний код виконується поза блоком try |
Типові помилки
- Думати, що
catchспрацьовує «на будь-яку помилку в програмі». Він бачить лише свій блокtryі виклики, що йдуть з нього синхронно. - Загортати
setTimeoutабоaddEventListenerуtryі чекати перехоплення. Обробляти треба всередині самого колбека. - Забувати
awaitперед асинхронним викликом. Без нього функція лише повертає promise, а відхилення стане unhandled rejection повзcatch. - Розраховувати, що після помилки виконається решта
try. Виконання обривається на рядку з помилкою, і жодний наступний рядок блоку не запуститься. - Мовчазний
catchбез логування. Помилка зникає, а баг лишається, і знайти його стає значно важче.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.