Typescript (или Javascript) Fetch API обрабатывает ошибки async / await - PullRequest
0 голосов
/ 24 мая 2019

Я хочу использовать асинхронный / удаленный синтаксис, Fetch API и хочу добиться следующего поведения:

если ответ не 200, запишите ответ, не бросайте ничего и возвращайте ноль. если ответ 200, вернуть ответ.

Но! Fetch API выдает исключение для всего, что отличается от 404, 505 или 200, и в итоге я получаю некрасивую конструкцию, подобную этой:

...
try{
 let response = await fetch(url, {method: 'GET', mode: 'cors'});
 if(response.status != 200){
    console.log('Failed to get what I want, got status: ' + response.status);
    return null;
 }
catch(e){
  console.log('error bla bla');
  return null;
}
...

Есть ли более элегантный способ добиться того же?

Ответы [ 4 ]

1 голос
/ 24 мая 2019

С MDN :

Обещание fetch () будет отклонено с ошибкой TypeError при сетевой ошибке встречается или неправильно настроен CORS на стороне сервера, хотя это обычно означает проблемы с разрешением или аналогичные - 404 не составляет ошибка сети, например.

И

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

Как сказал Гарри в своем ответе , я предлагаю создать промежуточное программное обеспечение для обработки неуспешных ответов или просто генерировать исключения, если статус не равен 200 или response.ok имеет значение false.

Пример (используется https://httpstat.us/):

async function getData() {
  try {
    let response = await fetch('https://httpstat.us/401', {
      method: 'GET',
      mode: 'cors'
    });
    if (!response.ok) throw response.statusText;
    console.log('Dataaa');

    return response
  } catch (e) {
    console.error(e);
    return null
  }
}

getData()
1 голос
/ 24 мая 2019

Fetch не выбрасывает в зависимости от кода состояния.Он выдаст сообщение, если возникнет сетевая ошибка, например, невозможность доступа к серверу.Это определено в спецификации Fetch.

Вот пример получения различных кодов состояния из Fetch

async function getit(status) {
  let url = 'https://httpstat.us/' + status
  try {
    let response = await fetch(url, {
      method: 'GET',
      mode: 'cors'
    });
    if (response.ok) {
      console.log("Got what we wanted")
    } else {
      console.log('Failed to get what I want, got status: ' + response.status);
    }
    return "okay";

  } catch (e) {
    console.log('A real error!');
    return "network error";
  }
}

getit(200).then(console.log)

// error codes
getit(400).then(console.log)
getit(503).then(console.log)
getit(401).then(console.log)

Пока он получает HTTP-ответ, он не должен выдавать.

(в вашем коде есть опечатка - вам не хватает закрывающей скобки на if (response.status != 200) {, но это должно вызвать синтаксическую ошибку, а не отклоненное обещание)

1 голос
/ 24 мая 2019

Если вы открыты для использования альтернативы fetch(), похоже, что у axios более чистая / настраиваемая обработка ошибок .На самом деле настройки по умолчанию полностью соответствуют вашему варианту использования.(Отклонить, если что-либо, кроме кода состояния 2XX):

try {
    let response = await axios.get(url, {mode: 'cors'});
    return response;
} catch (error) {
    if (error.response) {
        // The request was made and the server responded with a status code
        // that falls out of the range of 2xx
        console.log('Failed to get what I want, got status: ' + error.response.status);
    } else {
        console.log('error bla bla');
    }    
    return null;  
}

(Кстати, получение JSON с помощью axios - это всего лишь один шаг против двух шагов для r = await fetch(), затем r.json())

0 голосов
/ 24 мая 2019

Я бы сказал, создайте промежуточное ПО и назовите эту функцию промежуточного ПО, например fetch (). Then (middleware). Таким образом, он всегда будет использовать метод промежуточного программного обеспечения для каждого запроса, и вы можете добавить свой чек в одном месте.

...