最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Unable to catch 403 in try-catch during fetch - Stack Overflow

programmeradmin7浏览0评论

I'm making a put request using ReactJS, however, when I put in the wrong email/password bination, I get this logged on Chrome, even though I'm trying to catch all errors and show them in 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'), {
      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;
  }
}

I'm making a put request using ReactJS, however, when I put in the wrong email/password bination, I get this logged on Chrome, even though I'm trying to catch all errors and show them in 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.'), {
      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;
  }
}

Share Improve this question edited Sep 22, 2018 at 16:20 sideshowbarker 88.2k29 gold badges215 silver badges211 bronze badges asked Sep 22, 2018 at 15:54 Muhammad AliMuhammad Ali 3,5365 gold badges21 silver badges30 bronze badges 1
  • The code is ok. The problem cannot be replicated, stackblitz./edit/react-pb51rz – Estus Flask Commented Sep 22, 2018 at 16:02
Add a ment  | 

3 Answers 3

Reset to default 11

As per the mdn, fetch will throw only when a network error is encountered.
404 (or 403) are not a network error.

The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from pleting.

a 404 does not constitute a network error, for example. An accurate check for a successful fetch() would include checking that the promise resolved, then checking that the Response.ok property has a value of true

I pletely agree with @Sagiv, but there is a quick workaround to do that, although it is not a suggested way. Inside of try or promise.then(), you need to do this check.

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

So, by some simple checks it is possible to resolve or reject a promise. For e.g. in your case

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.', {
      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;
  }
}

I strongly remend using axios. For the fetch issue, you can refer to this link

This is because you throw Error and then catch part of your code does not execute. Try this:

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.'), {
      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;
  })
}
发布评论

评论列表(0)

  1. 暂无评论