【问题标题】:Async/Await in fetch() how to handle errorsfetch() 中的 Async/Await 如何处理错误
【发布时间】:2022-04-16 06:05:34
【问题描述】:

我的 React 应用程序中有条带异步代码,并试图在我的代码中添加错误处理,但不知道如何处理它。我知道如何使用 .then() 但 async/await 对我来说是新的

已编辑

添加了 .catch() 我在响应选项卡中的网络选项卡中出现错误。 但我可以将其记录到控制台?

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

谢谢

【问题讨论】:

  • 您要处理哪些错误?请告诉我们你会如何使用then
  • @MattWay 恰恰相反 - 如何在async/await 语法中catch
  • 请看更新的问题
  • 在catch部分,试试console.log(error)。只是一个建议,试试看。
  • console.log 在第二个 .catch 给我在网络选项卡和响应选项卡我有 {"name":"Name field is required","email":"Email is invalid","phone" :"Phone field is required","city":"City field is required","street":"Street field is required","country":"Country field is required"} 可以,但是如何访问呢? ?显示在前端?

标签: javascript reactjs asynchronous fetch


【解决方案1】:

Fetch 仅检测网络错误。其他错误(401、400、500)应手动捕获并拒绝。

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

如果您不习惯这种 fetch 限制,请尝试使用 axios。

【讨论】:

  • 你所说的“手动捕获和拒绝。”是什么意思?请举个例子。
  • Fetch 不会拒绝response.status &gt;= 400 &amp;&amp; response.status &lt; 600。它将它们视为异常,而不是错误。通过手动拒绝,我的意思是我们抛出的 else 部分捕获异常并抛出错误。
  • 抱歉,我完全错过了在您的代码中检查if (response.ok)(这比比较response.status 更好)。我一定把第一个 then 调用误认为是问题和其他答案中的 sn-ps 中的 options 参数。
  • 谢谢,真的,这是更清洁的方法。我只是想用我写的代码来传达 fetch 的响应处理。
  • 在给定的示例中,成功和失败都使用 Promise 处理。一开始有await 有什么意义?我没有改变任何东西,可以安全地删除。
【解决方案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);
        }

};

【讨论】:

    【解决方案3】:

    您可以像普通的命令式编程一样使用try/catch

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

    或者你可以混合搭配.catch(),就像你对承诺做的那样:

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

    【讨论】:

    • 我很确定第一个示例不会捕获请求错误。
    【解决方案4】:

    用 try catch 包装你的 await。

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

    【讨论】:

    • 仍然无法在前端出错...我的错误对象出现在网络选项卡中...
    【解决方案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});
          }
        }
    
    

    【讨论】:

      【解决方案6】:

      如果 response.ok 为 false,你可以抛出一个错误,然后在调用你的函数后链式 catch 方法如下

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

      【讨论】:

        【解决方案7】:

        如果服务器返回 { message: "some error" },则此方法有效,但我正试图让它也支持 res.statusText

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

        【讨论】:

          【解决方案8】:
           const data = {
                  token: token.id,
                  email,
                  price,
                  name,
                  phone,
                  city,
                  street,
                  country
                };
                axios
                  .post("/charge/pay", data)
                  .then(res => {
                    console.log(res);
                  })
                  .catch(err => {
                    console.log(err.response.data);
                  });
          

          【讨论】:

          • 问题是关于 fetch 的,在 Axios 中提供答案不是答案。
          猜你喜欢
          • 2018-09-03
          • 2021-10-30
          • 2021-12-31
          • 2021-10-24
          • 2016-08-04
          • 2023-01-05
          • 1970-01-01
          • 1970-01-01
          • 2019-02-14
          相关资源
          最近更新 更多