За обновлениями можно следить в telegram-канале https://t.me/quasiart

Fetch API не такой уж и новый, но знаете ли вы, как правильно обрабатывать ошибки при использовании этого API?

Посмотрите на код ниже, в котором сервер возвращает ошибку 404, каким будет сообщение в консоли: «Success» или «Failed»?

try {
  // сервер вернёт 404
  const response = await fetch('https://restcountries.com/v4.1/all')
  console.log('Success')
} catch {
  console.error('Failed')
}

Если вы предполагаете, что «Failed», то эта статья определенно для вас, потому что ваш ответ неверен. В консоли отобразится сообщение об успешном выполнении, и я расскажу вам, почему и как лучше обрабатывать ошибки.

Что такое Fetch API?

Fetch API — это интерфейс для выполнения асинхронных HTTP-запросов GET и POST.

Как обрабатывать ошибки Fetch API?

При использовании Fetch API могут возникать различные ошибки, такие как: ошибка сервера (500), «не найдено» (404), ошибка сети, ошибка CORS и т. д. И у нас есть разные подходы к обработке всех этих ошибок.

Использование try/catch

Fetch API возвращает промис, следовательно, мы можем использовать then, catch и finally.

Оборачивание запроса в try/catch — очень распространённый способ обработки ошибок (см. пример ниже), но не все ошибки можно перехватить.

try {
  // сервер вернёт ошибку CORS
  const response = await fetch('https://google.com/api')
} catch {
  console.error('Failed')
}
// Вывод в консоли: Failed

Этот код попытается выполнить выборку и обнаружить ошибки только в том случае, если обещание отклонено, что может произойти в следующих сценариях:

  • Сетевые ошибки: невозможность подключения к серверу, которая может быть вызвана, например, медленной сетью и таймаутом.
  • Ошибки CORS: когда домену не разрешено получать ресурсы из другого домена.

Fetch успешно выполнит промис даже при ошибках сервера (например, 404 и 500), поэтому catch не может их получить, как в примере в начале этой статьи.

Проверка статуса ответа

Другой способ обработки ошибок — проверка статуса ответа при успешном выполнении промиса:

// Сервер вернёт 404
const response = await fetch('https://restcountries.com/v4.1/all')

if (response.ok) {
  // Обработка ответа
} else {
  console.error('Failed')
}

Здесь мы используем response.ok, чтобы проверить успешность ответа.

  • response.ok равен true, когда код состояния находится между 200 и 299.
  • response.ok равен false, когда сервер возвращает любой другой статус, кроме указанного выше, например, 404, 500 и т.д.

Лучший способ обработки ошибок

Пример 0

try/catch и response.ok используются для обнаружения различных типов ошибок, поэтому мы можем объединить два подхода, чтобы лучше обрабатывать ошибки:

try {
  const response = await fetch('https://restcountries.com/v4.1/all')
  if (response.ok) {
    console.log('Promise resolved and HTTP status is successful')
  } else {
    console.error('Promise resolved but HTTP status failed')
  }
} catch {
  console.error('Promise rejected')
}

  • try/catch используется для получения ошибок, когда промис отклонён (проблемы с сетью или CORS).
  • response.ok используется для обработки ошибок сервера (например, 404 или 500), когда промис разрешён.

Пример 1

Другой распространённый способ обработки ошибок внутри блока try — выброс ошибки, когда значение response.ok равно false, чтобы выполнился блок catch, и мы могли обрабатывать все ошибки в одном и том же месте.

try {
  const response = await fetch('https://restcountries.com/v4.1/all');

  if (response.ok) {
    console.log('Promise resolved and HTTP status is successful');
  } else {
    // Индивидуальные сообщения для ошибочных HTTP-кодов
    if (response.status === 404) throw new Error('404, Not found');
    if (response.status === 500) throw new Error('500, internal server error');
    // Для остальных ошибок
    throw new Error(response.status);
  }
} catch (error) {
  console.error('Fetch', error);
  // Output e.g.: "Fetch Error: 404, Not found"
}

Здесь выбрасываются ошибки 404, 500 и прочие для их обработки в блоке catch, а также отображаются специальные сообщения в консоли в зависимости от типа ошибки.

  • когда response.ok возвращает false, мы можем просто выдать ошибку, поэтому будет выполнен блок catch.
  • catch будет обрабатывать все типы ошибок.
  • catch принимает аргумент, который можно настроить при выдаче ошибок из блока try.
  • response.status можно использовать для проверки возвращённого HTTP-кода состояния для отображения индивидуальных сообщений в консоли (например, 400, 404, 500…).

Рекомендации

  1. «Response: свойство ok» от MDN
  2. «HTTP-коды состояния ответа» от MDN
  3. «Использование Fetch API» от MDN