← Назад к вопросам

Как отловить ошибки через async/await?

1.3 Junior🔥 152 комментариев
#JavaScript Core

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обработка ошибок в async/await

async/await синтаксис позволяет обрабатывать асинхронные ошибки с помощью try/catch, что значительно понятнее, чем .catch() для промисов.

Базовая обработка с try/catch

Самый простой и читаемый способ:

async function fetchUser(id) {
  try {
    const response = await fetch(`/api/users/${id}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const user = await response.json();
    return user;
  } catch (error) {
    console.error('Ошибка при загрузке пользователя:', error);
    throw error;  // Пробросить ошибку дальше
  }
}

Обработка нескольких операций

Обрабатывай несколько async операций в одном блоке:

async function loadUserData(userId) {
  try {
    const userResponse = await fetch(`/api/users/${userId}`);
    const user = await userResponse.json();

    const postsResponse = await fetch(`/api/users/${userId}/posts`);
    const posts = await postsResponse.json();

    const commentsResponse = await fetch(`/api/posts/comments`);
    const comments = await commentsResponse.json();

    return { user, posts, comments };
  } catch (error) {
    console.error('Ошибка при загрузке данных:', error);
    return null;
  }
}

Promise.all() с обработкой ошибок

Для параллельных запросов используй Promise.all():

async function fetchAllData(ids) {
  try {
    const promises = ids.map(id => fetch(`/api/items/${id}`).then(r => r.json()));
    const results = await Promise.all(promises);
    return results;
  } catch (error) {
    console.error('Одна из операций не удалась:', error);
    throw error;
  }
}

// Или с Promise.allSettled() для частичного успеха:
async function fetchAllDataSafe(ids) {
  const promises = ids.map(id => fetch(`/api/items/${id}`).then(r => r.json()));
  const results = await Promise.allSettled(promises);

  const successful = results
    .filter(r => r.status === 'fulfilled')
    .map(r => r.value);

  const failed = results
    .filter(r => r.status === 'rejected')
    .map(r => r.reason);

  return { successful, failed };
}

Контекст ошибок (finally блок)

Используй finally для очистки ресурсов:

async function loadData() {
  let isLoading = true;

  try {
    const response = await fetch('/api/data');
    const data = await response.json();
    console.log('Данные загружены:', data);
    return data;
  } catch (error) {
    console.error('Ошибка загрузки:', error);
    return null;
  } finally {
    isLoading = false;  // Выполнится в любом случае
    console.log('Загрузка завершена');
  }
}

Типизация ошибок в TypeScript

Правильная обработка типов ошибок:

async function fetchData(): Promise<Data> {
  try {
    const response = await fetch('/api/data');
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    return response.json();
  } catch (error) {
    if (error instanceof TypeError) {
      console.error('Ошибка сети:', error.message);
    } else if (error instanceof SyntaxError) {
      console.error('Некорректный JSON:', error.message);
    } else if (error instanceof Error) {
      console.error('Неизвестная ошибка:', error.message);
    }
    throw error;
  }
}

Кастомные ошибки

Создавай кастомные классы ошибок для лучшей обработки:

class APIError extends Error {
  constructor(status, message) {
    super(message);
    this.status = status;
    this.name = 'APIError';
  }
}

async function apiCall(endpoint) {
  try {
    const response = await fetch(endpoint);
    if (!response.ok) {
      throw new APIError(response.status, response.statusText);
    }
    return response.json();
  } catch (error) {
    if (error instanceof APIError) {
      console.error(`API ошибка ${error.status}: ${error.message}`);
    }
    throw error;
  }
}

Wrapper для обработки ошибок

Часто используемый паттерн в приложениях:

const handle = (fn) => {
  return async (...args) => {
    try {
      return await fn(...args);
    } catch (error) {
      console.error(error);
      return null;  // или { error: error.message }
    }
  };
};

const safeLoad = handle(async (id) => {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
});

const user = await safeLoad(123);  // Автоматически обработает ошибки

Выбирай подходящий метод в зависимости от контекста: try/catch для основной логики, Promise.allSettled() для частичного успеха, и finally для очистки ресурсов.