Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

try to fetch and read the response body as json or fallback to plain text

I'm trying to fetch data from the server, and I want to try to resolve the response body as json, if failed return it as plain text

fetch(`/devapi/${url}`, {
    method: 'GET',
    headers: new Headers({
      Authorization: `Bearer ${localStorage.getItem("token")}`,
    }),
  })
    .then((res) =>
      res
        .json()
        .then((res) => res?.body?.data || res?.body || res)
        .catch((err) => res.text())
    )

    .then((val) => console.log(val));

when the response is NOT a valid json, ten res.text() is called, but it seems that calling .text() after .json causes an error

 Failed to execute 'text' on 'Response': body stream already read 
like image 318
Sh eldeeb Avatar asked Oct 31 '25 06:10

Sh eldeeb


1 Answers

You could clone the response, and then use it in error handler:

Try this:

fetch(`/devapi/${url}`, {
    method: 'GET',
    headers: new Headers({
      Authorization: `Bearer ${localStorage.getItem("token")}`,
    }),
  })
    .then((res) => {
      const clone = res.clone();
      return res
        .json()
        .then((res) => res?.body?.data || res?.body || res)
        .catch((err) => clone.text())
   })
    .then((val) => console.log(val));

or use XHR and process response in a try/catch:

const xhr = new XMLHttpRequest();
xhr.open('POST', `/devapi/${url}`, true);
xhr.setRequestHeader('Authorization', `Bearer ${localStorage.getItem("token")}`);
xhr.onload = function() {
    let res;
    try {
        res = JSON.parse(xhr.response);
    } catch (err) {
        res = xhr.responseText;
    }
    console.log(res);
};
xhr.send();
like image 121
traynor Avatar answered Nov 02 '25 20:11

traynor