Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Помилки в async функціях». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Помилки всередині **`async`-функцій** автоматично перетворюються на відхилений проміс (`Promise.reject`), тому для їх обробки використовують конструкцію `try...catch` або метод `.catch()` у поверненого промісу. **Ключове:** `await` "зупиняє" виконання функції, поки проміс не завершиться, і якщо він відхилений, `await` генерує виняток, який ловить `catch`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Основний принцип > Помилки всередині `async`-функцій **автоматично перетворюються на відхилений проміс (**`Promise.reject`**)**. > > Тому для їх обробки використовується або: > > - конструкція `try...catch`, > - або метод `.catch()` у поверненого промісу. --- ## 2. Приклад з `try...catch` (основний спосіб) ```javascript async function getData() { try { const res = await fetch("https://no-such-domain.com"); const data = await res.json(); console.log(data); } catch (error) { console.error("Сталася помилка:", error.message); } } getData(); ``` Вивід: ```javascript Сталася помилка: fetch failed ``` Тут `try...catch` працює **аналогічно синхронному коду**, але ловить помилки з усіх `await` всередині. --- ## 3. Чому це працює `await` "зупиняє" виконання функції, поки проміс не завершиться. Якщо проміс **відхилений (**`reject`**)**, `await` **генерує виняток**, і керування передається в `catch`. Приклад: ```javascript async function example() { const result = await Promise.reject("Помилка!"); console.log(result); // не виконається } example().catch(console.error); ``` Вивід: ```javascript Помилка! ``` --- ## 4. Помилка без try...catch -> проміс відхиляється Якщо не обгорнути `await` у `try...catch`, функція просто поверне **відхилений проміс**, який можна обробити через `.catch()`: ```javascript async function fail() { throw new Error("Щось пішло не так"); } fail().catch(err => console.error("Спіймали:", err.message)); ``` Вивід: ```javascript Спіймали: Щось пішло не так ``` Це еквівалентно обробці `.catch()` у звичайних промісах. --- ## 5. Кілька await - одна зона try Ти можеш обгортати **декілька** `await` **в один** `try`, якщо хочеш обробити всі помилки одним способом: ```javascript async function loadUserData() { try { const user = await fetch("/api/user"); const posts = await fetch("/api/posts"); const comments = await fetch("/api/comments"); } catch (e) { console.error("Помилка при завантаженні даних:", e); } } ``` Якщо будь-яка з операцій впаде - керування одразу перейде в `catch`. --- ## 6. Локальний try для точкового контролю Іноді краще обгортати **окремі await**, якщо ти хочеш обробляти помилки **по-різному**: ```javascript async function example() { try { const user = await fetchUser(); } catch (e) { console.error("Помилка при завантаженні користувача:", e); } try { const posts = await fetchPosts(); } catch (e) { console.error("Помилка при завантаженні постів:", e); } } ``` --- ## 7. Приклад: "зцілення" помилки (аналог `.catch().then()`) Якщо в `catch` повернути значення - функція продовжить виконуватися далі: ```javascript async function example() { try { await Promise.reject("Помилка!"); } catch (e) { console.log("Спіймали:", e); return "Значення за умовчанням"; } } example().then(result => console.log("Результат:", result)); ``` Вивід: ```javascript Спіймали: Помилка! Результат: Значення за умовчанням ``` --- ## 8. Помилки в паралельних `await` (Promise.all) Якщо ти виконуєш кілька `await` паралельно через `Promise.all`, і хоча б один з промісів відхилиться - весь `Promise.all` **впаде**. ```javascript async function parallel() { try { const [a, b] = await Promise.all([ Promise.resolve("ok"), Promise.reject("помилка"), ]); } catch (e) { console.log("Спіймали:", e); } } parallel(); ``` Вивід: ```javascript Спіймали: помилка ``` --- ## 9. Використання `catch` напряму (альтернатива try...catch) ```javascript async function getUser() { const res = await fetch("/api/user").catch(err => { console.error("Помилка при запиті:", err); return null; // повернемо безпечне значення }); console.log("Результат:", res); } getUser(); ``` Цей спосіб часто застосовують, якщо потрібно просто "придушити" помилку і продовжити виконання програми. --- ## 10. Найкращі практики | Ситуація | Що використовувати | |---|---| | Обробка помилок в одній функції | `try...catch` | | Обробка помилок при виклику async-функції | `.catch()` | | Різні типи помилок з різними реакціями | Кілька `try...catch` | | Кілька паралельних `await` | `Promise.allSettled()` замість `Promise.all` | | Логування і прокидання далі | `catch (e) { log(e); throw e; }` |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.