Проанализируйте JavaScript-код: async function f() { try { fetch('/data'); } catch (e) { console.log('error'); } } Почему блок catch не перехватывает ошибки сети, и как правильно обрабатывать ошибки асинхронных вызовов?
Проблема в том, что `fetch` возвращает Promise, а `try/catch` перехватывает только синхронные исключения или асинхронные — когда вы используете `await`. В вашем коде `fetch('/data')` запускается и сразу возвращает Promise; ошибка сети (или отклонение промиса) произойдёт позже, и уже не попадёт в синхронный `catch`. Ещё важно: `fetch` не считает HTTP‑ошибки (404, 500 и т.д.) ошибкой промиса — он «успешно» разрешится с объектом `Response`. Поэтому нужно проверять `response.ok` и при необходимости выбрасывать ошибку самому. Правильные варианты обработки: 1) с async/await и try/catch: async function f() { try { const res = await fetch('/data'); if (!res.ok) throw new Error(`HTTP ${res.status}`); const data = await res.json(); // обработка data } catch (e) { console.error('error', e); } } 2) с промис‑цепочкой: function f() { fetch('/data') .then(res => { if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.json(); }) .then(data => { /* обработка data */ }) .catch(e => console.error('error', e)); } 3) если нужен параллельный запрос: async function fAll() { try { const [r1, r2] = await Promise.all([fetch('/a'), fetch('/b')]); // проверить r1.ok / r2.ok и т.д. } catch (e) { console.error('error', e); } } Коротко: обёрните вызов `fetch` в `await` внутри `try` либо обработайте `.catch` на возвращаемом промисе; и дополнительно проверяйте `response.ok` для HTTP‑статусов.
Ещё важно: `fetch` не считает HTTP‑ошибки (404, 500 и т.д.) ошибкой промиса — он «успешно» разрешится с объектом `Response`. Поэтому нужно проверять `response.ok` и при необходимости выбрасывать ошибку самому.
Правильные варианты обработки:
1) с async/await и try/catch:
async function f() {
try {
const res = await fetch('/data');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
// обработка data
} catch (e) {
console.error('error', e);
}
}
2) с промис‑цепочкой:
function f() {
fetch('/data')
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then(data => { /* обработка data */ })
.catch(e => console.error('error', e));
}
3) если нужен параллельный запрос:
async function fAll() {
try {
const [r1, r2] = await Promise.all([fetch('/a'), fetch('/b')]);
// проверить r1.ok / r2.ok и т.д.
} catch (e) {
console.error('error', e);
}
}
Коротко: обёрните вызов `fetch` в `await` внутри `try` либо обработайте `.catch` на возвращаемом промисе; и дополнительно проверяйте `response.ok` для HTTP‑статусов.