fetch 发请求,接口报错,为什么拿不到错误信息
首先,如果API请求返回一个错误状态码(如404、500等),但是响应仍然成功返回(即没有网络问题或其他底层问题),fetch
不会抛出一个异常。它只有在网络问题或其他底层问题时才会抛出异常。为了正确处理API的HTTP错误状态码,你需要在检查响应后抛出一个错误。
让我们看一下如何改进你的fetchToken
函数来处理这种情况:
export async function fetchToken() {
const requestOptions = {}
try {
const response = await fetch("https://xxx", requestOptions);
// 检查响应状态码
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
} catch (error: any) {
throw error;
}
}
上述修改在fetch
后立即检查了HTTP响应的状态码,并在错误状态码的情况下抛出了错误。这样,你的catch
块就能捕获这个错误,并将其传递给外部调用者。
再次注意,错误可能来自于多个地方,包括:
fetch
自己的底层网络错误(这会导致fetch
抛出异常)。- API返回的HTTP错误状态码(如上所示,你需要手动处理这个)。
response.json()
解析错误(如果响应的内容不是有效的JSON,这将导致异常)。
确保你的代码能够捕获和处理这些不同的错误情况,并为用户提供有关错误的清晰反馈。
为什么要设计成这样
设计fetch
API以在网络故障或其他技术问题发生时抛出异常,而不是在HTTP错误状态码出现时抛出异常,是一个有意为之的设计选择。以下是这样设计的原因:
- 区分网络问题与HTTP响应 :
- 从技术角度看,即使HTTP响应返回了一个错误状态码,该请求仍然被成功完成了,因为它成功地从服务器接收到了一个响应。因此,从纯技术的意义上讲,这并不是一个“错误”。
- 另一方面,网络问题、跨域限制或其他阻止请求完成的底层问题确实是真正的错误,因此在这种情况下抛出异常是有意义的。
- 更大的灵活性 :
- 在许多应用中,可能需要根据不同的HTTP状态码执行不同的操作。例如,401未经授权的错误可能需要重新认证,而404找不到错误可能只需要显示一个消息。
- 如果
fetch
对所有HTTP错误状态码都抛出异常,那么处理这些情况会变得更加复杂。当前的设计允许开发者轻松地检查响应的状态码,并根据需要采取适当的行动。
- 与早期的XHR技术一致 :
fetch
API是XMLHttpRequest(XHR)的现代替代品,XHR也采用了相同的方法:它没有因HTTP错误状态码而抛出异常。虽然这并不是一个决定性的原因,但与以前的技术保持一致对许多开发者来说可能更加直观。
尽管这种设计可能初看起来不太直观,但当你习惯了之后,你会发现它实际上提供了更大的控制和灵活性。但是,确实需要开发者对HTTP响应进行额外的检查,并据此进行适当的错误处理。