Suggest an editImprove this articleRefine the answer for “Errors in async”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)Any **`async` function** always returns a promise. If it throws an error (`throw`) inside, the promise moves to the `rejected` state. **Key point:** errors can be handled in two ways - via `try...catch` inside the function itself, or via `.catch()` outside, at the call site.Shown above the full answer for quick recall.Answer (EN)Image## The main rule > Any `async` function **always returns a promise**. > If it throws an error (`throw`) inside, the promise moves to the `rejected` state. So errors can be handled in **two ways**: 1. via `try...catch` inside the function itself; 2. via `.catch()` outside, at the call site. --- ## 1. Handling via `try...catch` (inside the function) This is the **most readable and familiar way** - it resembles synchronous code. ```javascript async function getData() { try { const res = await fetch('https://api.github.com/404'); // network error const data = await res.json(); console.log('Received:', data); } catch (error) { console.error('Error inside async:', error.message); } } getData(); ``` **Output:** ```javascript Error inside async: Failed to fetch ``` `try...catch` "catches": - errors thrown via `throw`; - rejected promises that have `await` on them. --- ## How it works Under the hood, `await` does `try { ... } catch { ... }` for a promise that can end up with an error (`reject`). ```javascript const result = await Promise.reject('error'); // throws an exception → goes to the catch block ``` --- ## 2. Handling via `.catch()` (outside the function) Since an `async` function returns a `Promise`, you can handle the error with the regular `.catch()` method: ```javascript async function getUser() { const res = await fetch('https://wrong.url'); return res.json(); } getUser() .then(console.log) .catch(err => console.error('Error outside:', err.message)); ``` **Output:** ```javascript Error outside: Failed to fetch ``` The difference from `try...catch`: here the error is handled **at the call site**, not inside the function. --- ## 3. Example with a manual `throw` ```javascript async function example() { const data = await Promise.resolve('OK'); if (!data) throw new Error('No data!'); return data; } example() .then(console.log) .catch(err => console.error(err.message)); ``` **Output:** ```javascript OK ``` If the condition triggers, `throw` turns into `Promise.reject()`. --- ## 4. Combining `try...catch` with a re-`throw` Sometimes you need to **handle an error partially**, but pass it further - for example, to log it. ```javascript async function processData() { try { const res = await fetch('https://wrong.url'); return await res.json(); } catch (err) { console.error('Request error:', err.message); throw new Error('Error while processing data'); } } processData().catch(err => console.error('Final error:', err.message)); ``` **Output:** ```javascript Request error: Failed to fetch Final error: Error while processing data ``` --- ## 5. Handling several errors in a row You can use several `try...catch` blocks for different stages: ```javascript async function pipeline() { try { const res = await fetch('/api/data'); try { const data = await res.json(); console.log('Data:', data); } catch (err) { console.error('JSON parsing error:', err.message); } } catch (err) { console.error('Request error:', err.message); } } ``` This approach is useful when you need to handle different levels of errors separately. --- ## 6. Handling without `try...catch` (via a utility) Sometimes it's more convenient to use a helper function: ```javascript const to = (promise) => promise.then(data => [null, data]).catch(err => [err]); async function run() { const [err, data] = await to(fetch('/api/user').then(r => r.json())); if (err) return console.error('Error:', err.message); console.log(data); } ``` This pattern is often used in Node.js, so you don't have to write `try...catch` at every step. --- ## 7. A global catch for unhandled errors If you forget `.catch()` or `try...catch`, you can catch the error globally: ```javascript window.addEventListener('unhandledrejection', (event) => { console.error('Unhandled promise:', event.reason); }); ``` This is the equivalent of `try...catch` for every promise that has no `.catch()`. --- ## A simple analogy > Think of an `async` function as a quest. > > - `await` is a "task" that can fail; > - `try...catch` is "insurance": if it fails, you catch the error and decide what to do; > - `.catch()` outside is the "game master" who catches fatal errors if the player did not manage. --- ## SUMMARY | Way | Where it catches the error | Example | |---|---|---| | `try...catch` | inside the `async` function | `try { await ... } catch (e) { ... }` | | `.catch()` | at the function call | `myAsync().catch(e => ...)` | | **Global catch** | for all unhandled ones | `window.addEventListener('unhandledrejection', ...)` | | **The** `[err, data]` **pattern** | via a wrapper | `const [err, res] = await to(promise)` |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.