在获取期间无法在 try-catch 中捕获 403
Posted
技术标签:
【中文标题】在获取期间无法在 try-catch 中捕获 403【英文标题】:Unable to catch 403 in try-catch during fetch 【发布时间】: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;
【问题讨论】:
代码没问题。问题无法复制,stackblitz.com/edit/react-pb51rz 【参考方案1】:根据mdn,fetch
只会在遇到网络错误时抛出。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 本身内。以上是关于在获取期间无法在 try-catch 中捕获 403的主要内容,如果未能解决你的问题,请参考以下文章