【问题标题】:Unable to catch 403 in try-catch during fetch在获取期间无法在 try-catch 中捕获 403
【发布时间】:2019-02-26 17:25:47
【问题描述】:

我正在使用 ReactJS 发出 put 请求,但是,当我输入错误的电子邮件/密码组合时,我会在 Chrome 上登录,即使我试图捕获所有错误并将它们显示在 errorDiv

async connect(event) {
  try {
    const userObject = {
      username: this.state.userName,
      password: this.state.password
    };
    if (!userObject.username || !userObject.password) {
      throw Error('The username/password is empty.');
    }
    let response = await fetch(('someurl.com'), {
      method: "PUT",
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(userObject)
    });
    let resJSON = await response.json();
    if (!response.ok) {
      throw Error(resJSON.message);
    }
    console.info(resJSON.message);
    console.info(resJSON.message.auth_token);
    window.location = "/ledger/home";
  } catch (e) {
    document.getElementById("errorDiv").style.display = 'block';
    document.getElementById("errorDiv").innerHTML = e;
  }
}

【问题讨论】:

标签: javascript reactjs put http-status-code-403 fetch-api


【解决方案1】:

根据mdnfetch 只会在遇到网络错误时抛出。
404(或403)不是网络错误。

即使响应是 HTTP 404 或 500,从 fetch() 返回的 Promise 也不会拒绝 HTTP 错误状态。相反,它会正常解析(将 ok 状态设置为 false),并且只会拒绝网络故障或是否有任何事情阻止请求完成。

例如,404 不构成网络错误。对成功 fetch() 的准确检查包括检查 promise 是否已解决,然后检查 Response.ok 属性的值是否为 true

【讨论】:

  • 所以我无法捕捉到它并将其显示给用户,而不是自动创建日志?
【解决方案2】:

我完全同意@Sagiv,但是有一个快速的解决方法可以做到这一点,尽管这不是建议的方法。 在 try 或 promise.then() 中,你需要做这个检查。

const res = await fetch();
console.log(res);    // You can see the response status here by doing res.status

因此,通过一些简单的检查,可以解决或拒绝一个承诺。例如在你的情况下

async connect(event) {
  try {
    const userObject = {
      username: this.state.userName,
      password: this.state.password
    };
    if (!userObject.username || !userObject.password) {
      throw Error('The username/password is empty.');
    }
    let response = await fetch('someurl.com', {
      method: 'PUT',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(userObject)
    });
    if (response.status === 403) throw new Error('403 is unacceptable for me!');
    let resJSON = await response.json();
    if (!response.ok) {
      throw Error(resJSON.message);
    }
    console.info(resJSON.message);
    console.info(resJSON.message.auth_token);
    window.location = '/ledger/home';
  } catch (e) {
    document.getElementById('errorDiv').style.display = 'block';
    document.getElementById('errorDiv').innerHTML = e;
  }
}

我强烈建议使用axios。 fetch问题可以参考这个link

【讨论】:

    【解决方案3】:

    这是因为您抛出错误,然后捕获部分代码未执行。试试这个:

    async connect(event) {
      try {
        const userObject = {
          username: this.state.userName,
          password: this.state.password
        };
        if (!userObject.username || !userObject.password) {
          throw Error('The username/password is empty.');
        }
        let response = await fetch(('someurl.com'), {
          method: "PUT",
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(userObject)
        }).then(response => {
           response.json();
           console.info(resJSON.message);
           console.info(resJSON.message.auth_token);
           window.location = "/ledger/home";
        }).catch(e => {
        document.getElementById("errorDiv").style.display = 'block';
        document.getElementById("errorDiv").innerHTML = e;
      })
    }
    

    【讨论】:

    • 我是否在最后一行之后添加另一个捕获?由于 .catch 在 try 本身内。
    猜你喜欢
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多