Fetch API: как определить, является ли ошибка сетевой ошибкой - PullRequest
0 голосов
/ 09 апреля 2020

Итак, у меня есть такой код:

async function getData() {
  const response = await fetch(/* ... */);
  const json = await response.json();
  return transform(json);
}

Где transform может выдавать некоторые собственные ошибки.


Я пытаюсь отловить ошибки сети из fetch API.

try {
  const data = await getData();

  // ...
  return // ...
} catch (e) {
  if (isNetworkError(e)) {
    return localStorage.getItem('...');
  }

  throw e;
}

Мой вопрос заключается в том, как реализовать isNetworkError, который работает в разных браузерах? Примечание: это должно возвращать значение true, только если сеть отключена .

Кажется, что и chrome, и firefox выдают TypeError, но у них разные сообщения.

  • Firefox: TypeError: "NetworkError when attempting to fetch resource."
  • Chrome: TypeError: Failed to fetch

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

Если первое обещание отклонено, это ошибка сети. Это единственный раз, когда это происходит.

Обещание, возвращаемое функцией fetch (), не будет отклонять состояние ошибки HTTP, даже если ответом является HTTP 404 или 500. Вместо этого он будет разрешаться нормально (с ok status установлен в false), и он будет отклоняться только при сбое сети или если что-либо помешает завершению запроса.

Со страницы разработчика Mozilla: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

0 голосов
/ 09 апреля 2020

У меня нет идеального ответа для вас. Самым простым для решения вашей точной проблемы является реализация isNetworkError для защиты типов. Возможно, в объекте ошибок firefox / chrome есть общие свойства, которые позволяют вам конкретно определять эти.

Альтернатива - перехватывать ошибки ближе к месту, где вы делаете fetch(), и повторно выводить ошибку как нечто, что вы можете легко обнаружить.

async function getData() {
  let response;

  try {
    response = await fetch(/* ... */);
  } catch (err) {
    throw new MyCustomNetworkError(err.message);
  }
  const json = await response.json();
  return transform(json);
}
...