Как обработать ответ .json и .text, используя fetch? - PullRequest
1 голос
/ 20 мая 2019

Я получаю API, который возвращает json, но когда он имеет ошибку, он возвращает только текст (В узле с экспрессом результаты возвращаются с .json({}) и ошибками с .send('string')), но Я не могу изменить API

Так что я пытаюсь сделать что-то, что читает json, но если это текст, он войдет в .catch, где ошибка - текст.

Вот то, что я пытался, но безуспешно.

fetch(apiUrl)
    .then(res => {
        try {
            let json = res.json()
            return json
        } catch (error) {
            return new Promise((resolve, reject) => reject(res.text()))
        }
    })
    .then(res => {
        // get result from res.json() **res == res.json**
    })
    .catch(error => {
        // get result from res.text() **res == res.text**
    })

Как мне этого добиться?Как получить res.json() в следующем .then(), но в случае неудачи получить res.text() в .catch?

Редактировать:

Я хочу получить .text в.catch.Я не знаю почему, но бросание res.text() не работает.

Ответы [ 2 ]

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

В идеале ваше клиентское приложение должно знать , какой тип ответа ожидать, и иметь статический код, вызывающий соответствующий метод.


Еще один способ справиться с ситуацией - проверить ответ contentType и вызвать .json() или .text() в зависимости от значения заголовка конкретного ответа.

handleResponseStatusAndContentType(response) {
  const contentType = response.headers.get('content-type')!;

  if (response.status === 401) throw new Error('Request was not authorized.');

  if (contentType === null) return new Promise(() => null);
  else if (contentType.startsWith('application/json;')) return response.json();
  else if (contentType.startsWith('text/plain;')) return response.text();
  else throw new Error(`Unsupported response content-type: ${contentType}`);
}

Использование:

return fetch(
  url,
  requestInit,
)
.then(response => handleResponseStatusAndContentType(response))
.catch(error => {
  console.error(error);
  return error;
});
0 голосов
/ 22 мая 2019

Другой подход заключается в том, чтобы сначала просто отформатировать все в текст, а затем попытаться проанализировать его, одновременно выдавая ошибку в случае проблем с синтаксическим анализом.

fetch("http://maps.googleapis.com/maps/api/geocode/json?address=google")
    .then(res => res.text())
    .then(body => {
        try {
            return JSON.parse(body);
        } catch {
            throw Error(body);
        }
    })
    .then(console.log)
    .catch(console.error);

fetch("http://maps.googleapis.com/maps/api/geocode/xml?address=google")
    .then(res => res.text())
    .then(body => {
        try {
            return JSON.parse(body);
        } catch {
            throw Error(body);
        }
    })
    .then(console.log)
    .catch(console.error);
...