Capturing Responses other than 200 OK From Fetch
Asked Answered
S

2

6

I'm using the native fetch library as specified here. It seems that whenever a response other than a 200 OK is returned it throws an exception with the string response Uncaught (in promise) TypeError: Failed to fetch.

Was there a way to catch and branch on specific HTTP response codes and still view the response data? For example a 401 response?

I have attached my request code I am using as a wrapper for fetch.

static request(url, data) {

    let headers = {
        "Authorization": window.localStorage.getItem("Authorization"),
        "Content-Type": "application/json"
    };

    let options = {
        method: "GET",
        headers: headers,
        mode: "no-cors",
        cache: "no-cache",
    };

    if (data) {
        options = {
            method: "POST",
            headers: headers,
            mode: "no-cors",
            cache: "no-cache",
            body: JSON.stringify(data)
        }
    }

    return new Promise(async (resolve, reject) => {

        try {

            let response = await fetch(url, options);
            let jsonResponse = await response.json();
            return resolve(jsonResponse);

        } catch (error) {
            // hashHistory.push("/login");
            return reject(error);
        }

    })

}   
Salchunas answered 11/7, 2017 at 1:48 Comment(3)
Generally speaking you never need to construct a Promise object yourself. You can await fetch directly in your request function.Ray
Never ever pass an async function to new Promise!Selfregard
I think this is the main source of the issue! Thanks for the code reviewSalchunas
F
8

"An accurate check for a successful fetch() would include checking that the promise resolved, then checking that the Response.ok property has a value of true. The code would look something like this (https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful):

fetch('flowers.jpg').then(function(response) {
  if(response.ok) {
    response.blob().then(function(myBlob) {
      var objectURL = URL.createObjectURL(myBlob);
      myImage.src = objectURL;
    });
  } else {
    console.log('Network response was not ok.');
  }
})
.catch(function(error) {
  console.log('There has been a problem with your fetch operation: ' + error.message);
});

"

Flamethrower answered 11/7, 2017 at 1:54 Comment(0)
R
2

You can check Response Headers .status property, .text() to read Response. If Response is expected to be read more than once, you can use .clone()

let request = fetch("/path/to/resource");

request
.then(response => {
   
    const status = response.status

    console.log(status);

    if (status == 401) {
      // read 401 response
      response.text().then(res = > console.log(res));
      return "404.html"
    }
    if (status == 200) {
      return "200.html"
    }
})
.then(result => console.log(result))
.catch(err => // handle error);
Rasorial answered 11/7, 2017 at 2:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.