简体   繁体   中英

How to use returned JSON error in a JavaScript async fetch call

I have an async fetch call which calls my backend to create a customer with an email address. If successful, the JSON returned is sent to a doNextThing() function.

If the backend returns a non-200 status code it also returns JSON like {"message": "Something went wrong"} . I want to catch the error and send that message to the console .

I've read dozens of slightly similar questions and edged close to an answer. So far I have the below, but if the backend's response was a 403 status code, for example, then the console outputs "FORBIDDEN". I think this is because the promise hasn't yet resolved, so doesn't yet have the full JSON response. Or something. But I can't work out what I'm missing.

async function createCustomer(email) {
  return fetch("/api/create-customer", {
    method: "post",
    headers: {"Content-Type": "application/json"},
    body: JSON.stringify({email: email})
  })
    .then(function(response) {
      if (response.ok) {
        return response.json();
      } else {
        return Promise.reject({
          status: response.status,
          statusText: response.statusText
        });
      }
    })
    .then(function(returned_data) {
      doNextThing(returned_data);
    })
    .catch(function(e) {
      console.error(e.statusText);
    });
}

Personally I recommend the async/await syntax if the version you're using supports it. It really simplifies the code and allows you to easily use the try/catch syntax.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#Browser_compatibility

It seems it doesn't work in IE though if that's a dealbreaker.

async function createCustomer(email) {
try {
    const response = await fetch("/api/create-customer", {
        method: "post",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: email })
    })
    if (response.ok) {
        const returnedData = await response.json();
        // if doNextThing is an async function, you can await it as well or just return it 
        doNextThing(returnedData);
    } else {
        throw {
            json: await response.json()
            status: response.status,
            statusText: response.statusText
        };
    }
} catch (requestErr) {
    // do what you like with the error
    // this will be called if you "throw" above or 
    // if fetch() rejects
    if (requestErr.json){
        console.error(JSON.stringify(requestErr.json));
    }
    console.error("Request err:" + requestErr);
}

}

Let me know if that helps.

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