'Async/Await in fetch() how to handle errors

I have stripe async code in my React app, and trying to add error handling in my code but have no idea how to handle it. i know how to do it with .then() but async/await is new to me

EDITED

added .catch() i got errors in network tab in response tab. but i can log it to console?

    submit = async () => {
    const { email, price, name, phone, city, street, country } = this.state;
    let { token } = await this.props.stripe
      .createToken({
        name,
        address_city: city,
        address_line1: street,
        address_country: country
      })
      .catch(err => {
        console.log(err.response.data);
      });

    const data = {
      token: token.id,
      email,
      price,
      name,
      phone,
      city,
      street,
      country
    };

    let response = await fetch("/charge/pay", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    }).catch(err => {
      console.log(err.response.data);
    });
    console.log(response);
    if (response.ok)
      this.setState({
        complete: true
      });
  };

thanks



Solution 1:[1]

Fetch detects only network errors. Other errors (401, 400, 500) should be manually caught and rejected.

await fetch("/charge/pay", headers).then((response) => {
    if (response.status >= 400 && response.status < 600) {
      throw new Error("Bad response from server");
    }
    return response;
}).then((returnedResponse) => {
   // Your response to manipulate
   this.setState({
     complete: true
   });
}).catch((error) => {
  // Your error is here!
  console.log(error)
});

If you are not comfortable with this limitation of fetch, try using axios.

Solution 2:[2]

var handleError = function (err) {
    console.warn(err);
    return new Response(JSON.stringify({
        code: 400,
        message: 'Stupid network Error'
    }));
};

var getPost = async function () {

    // Get the post data
    var post = await (fetch('https://jsonplaceholder.typicode.com/posts/5').catch(handleError));

    // Get the author
    var response = await (fetch('https://jsonplaceholder.typicode.com/users/' + post.userId).catch(handleError));

       if (response.ok) {
            return response.json();
        } else {
            return Promise.reject(response);
        }

};

Solution 3:[3]

You can either use try/catch just like normal, imperative programming:

try {
    let response = await fetch("/charge/pay", {
      method: "POST",
      headers: {
          "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    });
} catch(error) {
    // Error handling here!
}

Or you can mix-and-match .catch() just like you do with promises:

let response = await fetch("/charge/pay", {
    method: "POST",
    headers: {
       "Content-Type": "application/json"
    },
    body: JSON.stringify(data)
}).catch(function(error) {
    // Error handling here!
});

Solution 4:[4]

Wrap your await with try catch.

try {
    let response = await fetch("/charge/pay", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    });

    console.log(response);
} catch (error) {
    console.log(error);
}

Solution 5:[5]

 async function loginWithRedirect(payload: {
        username: string;
        password: string;
    }) {
      const resp = await (await fetch(`${env.API_URL}/api/auth/login`, {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify(payload),
        credentials: "include",
      })).json();
      if (resp.error) {
        dispatch({type: "ERROR", payload: resp.error.message});
      } else {
        dispatch({type: "LOGIN", payload: resp});
      }
    }

Solution 6:[6]

If response.ok is false you can throw an error then chain catch method after calling your function as follows

async function fetchData(){
    const response = await fetch("/charge/pay", {
      method: "POST",
      headers: {
          "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    });

    if(!response.ok){
        const message = `An error occured: ${response.status}`;
        throw new Error(message);
    }
    
    const data = await response.json();
    return data;
}

fetchData()
    .catch(err => console.log(err.message));

Solution 7:[7]

This works if server returns { message: "some error" } but I'm trying to get it to support res.statusText too:

        try {
            const res = await this.fetch(path, {
                method: opts.method || 'GET',
                body: method === 'GET' ? null : body,
                headers
            });

            if (res.ok) {
                return await (opts.raw ? res.text() : res.json());
            }

            const err = await res.json();

            throw new Error(err.message || err.statusText);
        } catch (err) {
            throw new Error(err);
        }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yazan Rawashdeh
Solution 2 Ishan Garg
Solution 3
Solution 4 Win
Solution 5 sounish nath
Solution 6 hkiame
Solution 7 chovy