每当您使用 axios 进行后端 API 调用时,您都必须考虑如何处理.catch()
。现在,您可能认为您的 API 是高度可用的,并且会 24/7 全天候运行。您可能认为用户工作流程非常清晰,您的 javascript 很健全,并且您有单元测试。因此,当您在使用发出请求时盯着 catch 块时,axios
您可能会想 - “好吧...我将控制台记录它。这样就可以了。”
axios.get('/my-highly-available-api').then(response => {
// do stuff
})
.catch(err => {
// what now?
console.log(err);
})
但是,在发出 API 请求时,还有很多超出您控制范围的事情可能会引发错误。你可能甚至不知道它们正在发生!
以下是使用 axios 时可能出现的 3 种错误类型以及如何处理它。
捕获 axios 错误
下面是我开始包含在一些 JS 项目中的片段。
axios.post(url, data).then(res => {
// do good things
})
.catch(err => {
if (err.response) {
// client received an error response (5xx, 4xx)
} else if (err.request) {
// client never received a response, or request never left
} else {
// anything else
}
})
每个条件都旨在捕获不同类型的错误。
检查 error.response
如果您的错误对象包含一个response
字段,则意味着您的服务器响应了 4xx/5xx 错误。通常这是我们最熟悉的错误,也是最容易处理的。
如果您的 API 返回 404,请执行诸如显示 404 Not Found 页面/错误消息之类的操作。如果您的后端返回 5xx 或根本不返回任何内容,则显示不同的错误消息。你可能认为你的架构良好的后端不会抛出错误 - 但它是时间问题,而不是如果。
检查 error.request
第二类错误是您没有响应但错误附加了请求字段。这什么时候发生?当浏览器能够发出请求但由于某种原因没有看到响应时,就会发生这种情况。
在以下情况下可能会发生这种情况:
- 你在一个不稳定的网络中(想想地下地铁或建筑无线网络)
- 如果您的后端挂在每个请求上并且没有按时返回响应
- 如果您提出跨域请求并且您无权提出请求
- 如果您进行跨域请求并获得授权,但后端 API 返回错误
此错误的更常见版本之一有一条消息“网络错误”,这是一条无用的错误消息。我们有一个前端和一个后端 api 托管在不同的域上,因此每个后端 API 调用都是跨域请求。
由于浏览器中 JS 的安全限制,如果您发出 API 请求,并且由于糟糕的网络而失败,您将看到的唯一错误是“网络错误”,这非常无用。它可以意味着从“您的设备没有互联网连接”到“您的选项返回 5xx”(如果您发出 CORS 请求)。
所有其他类型的错误
如果您的错误对象上没有response
orrequest
字段,则意味着它不是 axios 错误,并且您的应用程序中可能还有其他错误。错误消息 + 堆栈跟踪应该可以帮助您找出它的来源。
你如何解决它?
降低用户体验
这一切都取决于您的应用程序。对于我从事的项目,对于使用这些端点的每个功能,我们都会降低用户体验。
例如,如果请求失败,并且页面没有这些数据就无用,那么我们会出现一个更大的错误页面,并为用户提供一条出路——有时只是一个“刷新页面”按钮。
另一个示例,如果对社交媒体流中的个人资料图片的请求失败,我们可以显示占位符图像并禁用个人资料图片更改,以及解释为什么禁用“更新个人资料图片”按钮的烤面包机消息。但是,显示“422 Unprocessable Entity”的警报对于用户来说是无用的。
参差不齐的网络
我工作的网络客户端用于学校网络,这绝对是可怕的。后端的可用性与它几乎没有任何关系,请求有时无法离开学校网络。
为了解决这些类型的间歇性网络问题,我们添加了axios-retry。这解决了我们在生产中看到的大量错误。我们将此添加到我们的 axios 设置中:
const _axios = require('axios')
const axiosRetry = require('axios-retry')
const axios = _axios.create()
// https://github.com/softonic/axios-retry/issues/87
const retryDelay = (retryNumber = 0) => {
const seconds = Math.pow(2, retryNumber) * 1000;
const randomMs = 1000 * Math.random();
return seconds + randomMs;
};
axiosRetry(axios, {
retries: 2,
retryDelay,
// retry on Network Error & 5xx responses
retryCondition: axiosRetry.isRetryableError,
});
module.exports = axios;
我们能够看到 10% 的用户(在蹩脚的学校网络中)看到零星的“网络错误”,并且在添加失败的自动重试后下降到 <2%。
^ 这是我们错误的屏幕截图,它们是“网络错误”的计数,因为它们出现在 NewRelic 中,并且显示 <1% 的请求出错了。
这引出了我的最后一点:
向前端添加错误报告
有前端错误/事件报告很有帮助,这样你就可以在用户告诉你之前知道生产中发生了什么。在我的日常工作中,我们使用 NewRelic Browser(付费服务 - 没有从属关系,只是一个粉丝)从前端发送错误事件。因此,每当我们捕获异常时,我们都会记录错误消息以及堆栈跟踪(尽管有时这对缩小的包没有用)以及有关当前会话的一些元数据,以便我们可以尝试重新创建它。
如果您对此一无所获,请做一件事。
现在转到您的代码库,并查看您如何使用 axios 处理错误。
- 检查您是否正在执行自动重试,
axios-retry
如果没有,请考虑添加 - 检查您是否正在捕获错误,并让用户知道发生了一些事情。
axios.get(...).catch(console.log)
不够好。
所以。你如何处理你的错误?在评论中告诉我。
顺便说一下,我目前正在编写一本新的电子书,以帮助初学者网络开发人员使用 javascript 在网络上构建和发布他们的想法,最快一个周末。
如果您刚刚想出了一个关于 Web 应用程序的好主意,但不确定如何开始使用它,或者当您尝试自己启动一个应用程序时会出现“空白页”综合症——您需要检查一下出去
阅读有关这本书的更多信息,并获取一份免费章节的副本,其中介绍了如何判断您的 Web 应用程序是否按照预期的方式工作
发表评论
所有评论(0)
非常好,赞同~