如何使用 axios 处理 Web 应用程序中的 API 错误

每当您使用 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 请求)。

所有其他类型的错误

如果您的错误对象上没有responseorrequest字段,则意味着它不是 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 应用程序是否按照预期的方式工作

相关标签:
  • API异常处理
  • axios
  • error.response
2人点赞

发表评论

当前游客模式,请登陆发言

所有评论(0)

用户头像
I have a dream

非常好,赞同~