简体   繁体   中英

How to handle response .json and .text using fetch?

I'm fetching an API that returns a json but when it has an error, it returns only a text (In node with express, results are returned with .json({}) and errors with .send('string') ), but I can't modify the API

So I'm trying to make something that reads the json, but if it's an text, it will go in .catch where the error is the text.

Here is what I have tried but with no success.

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**
    })

How can I achieve this? How to get res.json() in the next .then() but if it fails, get res.text() in the .catch ?

Edit:

I want to get the .text in .catch . I don't know why, but throwing res.text() doesn't work.

Ideally, your client application should know what response kind to expect and have static code that calls the appropriate method.


Another way to deal with your situation is to inspect the response contentType and call .json() or .text() depending on particular response header value.

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

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

  if (contentType === null) return Promise.resolve(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}`);
}

Usage:

return fetch(
  url,
  requestInit,
)
.then(response => handleResponseStatusAndContentType(response))
.catch(error => {
  console.error(error);
  return error;
});

Another approach would be to simply format eveyrthing to text initially and only then try to parse it, while throwing an error in case of parsing issues.

 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM