fetch() 中的 Async/Await 如何处理错误

Exc*_*Exc 28 javascript asynchronous fetch reactjs

我的 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
      });
  };
Run Code Online (Sandbox Code Playgroud)

谢谢

Ava*_*ika 37

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

Run Code Online (Sandbox Code Playgroud)

如果您对 fetch 的这种限制不满意,请尝试使用 axios。

  • Fetch 不会拒绝 `response.status &gt;= 400 &amp;&amp; response.status &lt; 600`。它将它们视为异常,而不是错误。通过手动拒绝,我的意思是我们抛出捕获异常并抛出错误的 else 部分。 (3认同)
  • 抱歉,我完全错过了代码中的“if (response.ok)”检查(在我看来,这比比较“response.status”更好)。我一定把第一个“then”调用误认为是选项参数,就像问题和其他答案中的片段一样。 (3认同)
  • 在给定的示例中,成功和失败都是使用 Promise 来处理的。一开始的“await”有什么意义?我不会改变任何东西并且可以安全地删除。 (3认同)
  • 不要同时使用 async/await 和 Promise 模式 (`.then`)。对于良好的“fetch”错误处理实践,我建议阅读 https://web.dev/fetch-api-error-handling/ (2认同)

Ish*_*arg 11

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

};
Run Code Online (Sandbox Code Playgroud)


Lir*_*una 5

您可以像普通的命令式编程一样使用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!
}
Run Code Online (Sandbox Code Playgroud)

或者你可以.catch()像使用 promise 一样混合搭配:

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

  • 我很确定第一个示例不会捕获请求错误。 (18认同)
  • 第一个示例确实捕获了第二个示例中也会处理的相同错误。但如果 url 正在响应,例如。404 不会处理任何错误。这是因为即使服务器返回的响应告诉您未找到资源,提取也会成功。 (6认同)
  • 第一个示例没有捕获错误。 (3认同)
  • 胜利势在必行,谢谢 LiraNuna。 (2认同)

cho*_*ovy 5

如果服务器返回,这会起作用{ message: "some error" },但我也试图让它支持res.statusText

        const path = '/api/1/users/me';
        const opts = {};
        const headers = {};
        const body = JSON.stringify({});
        const token = localStorage.getItem('token');

        if (token) {
          headers.Authorization = `Bearer ${token}`;
        }

        try {
            const res = await fetch(path, {
                method: opts.method || 'GET',
                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);
        }
Run Code Online (Sandbox Code Playgroud)


Win*_*Win 2

用 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);
}
Run Code Online (Sandbox Code Playgroud)

  • 前端仍然无法收到错误...我的错误对象出现在网络选项卡中... (2认同)