Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Обработка исключений в Promise
Обработка ошибок в Promise - критически важная часть асинхронного программирования на JavaScript/TypeScript. Существует несколько способов отловить и обработать исключения.
Метод .catch()
Это самый простой и классический способ обработки ошибок в Promise цепочке:
fetch('/api/users')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => {
console.error('Ошибка при загрузке:', error);
});
Метод .catch() перехватывает любую ошибку из цепочки Promise - как из rejected промиса, так и из выброшенного исключения в .then() блоках.
Async/Await с try/catch
Современный и более читаемый подход с использованием async/await:
async function fetchUsers() {
try {
const response = await fetch('/api/users');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
return data;
} catch (error) {
console.error('Ошибка:', error);
// Перебросить или обработать
throw error;
} finally {
console.log('Загрузка завершена');
}
}
Обработка разных типов ошибок
async function processData() {
try {
const response = await fetch('/api/data');
const data = await response.json();
} catch (error) {
if (error instanceof TypeError) {
console.error('Ошибка сети:', error);
} else if (error instanceof SyntaxError) {
console.error('Ошибка парсинга JSON:', error);
} else {
console.error('Неизвестная ошибка:', error);
}
}
}
Promise.all() с обработкой ошибок
// Вариант 1: любая ошибка отменяет всё
Promise.all([promise1, promise2, promise3])
.then(results => console.log('Успех:', results))
.catch(error => console.error('Одна из ошибок:', error));
// Вариант 2: обрабатываем каждую ошибку отдельно
Promise.allSettled([promise1, promise2, promise3])
.then(results => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Promise ${index} успешен:`, result.value);
} else {
console.error(`Promise ${index} ошибка:`, result.reason);
}
});
});
Обработка ошибок с повторными попытками
async function fetchWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (error) {
if (i === maxRetries - 1) throw error;
console.log(`Попытка ${i + 1} не удалась, повторяю...`);
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
Custom Error классы
class APIError extends Error {
constructor(message, statusCode) {
super(message);
this.name = 'APIError';
this.statusCode = statusCode;
}
}
async function fetchData() {
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new APIError(
`Ошибка сервера: ${response.statusText}`,
response.status
);
}
return await response.json();
} catch (error) {
if (error instanceof APIError) {
console.error(`API Ошибка [${error.statusCode}]:`, error.message);
} else {
console.error('Системная ошибка:', error);
}
}
}
Лучшие практики
1. Всегда обрабатывай ошибки - неуловленное отклонение Promise вызывает unhandledrejection событие:
window.addEventListener('unhandledrejection', event => {
console.error('Необработанная ошибка Promise:', event.reason);
});
2. Не оставляй catch пустым:
// Плохо
fetch('/api').catch(() => {});
// Хорошо
fetch('/api').catch(error => {
console.error('Ошибка загрузки:', error);
// Показать пользователю или логировать
});
3. Различай HTTP ошибки и сетевые ошибки:
async function safeFetch(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response;
} catch (error) {
if (error instanceof TypeError) {
// Сетевая ошибка
console.error('Нет соединения');
} else {
// HTTP ошибка
console.error(error.message);
}
throw error;
}
}
Правильная обработка ошибок в Promise делает приложение более надёжным и улучшает пользовательский опыт.