node.js - 如何使用适配器更改 Axios 中的结果状态?

标签 node.js axios adapter axios-retry

原因

我们正在使用 axios-retry库,它在内部使用此代码:

axios.interceptors.response.use(null, error => {

由于它仅指定错误回调,因此 Axios documentation说:

Any status codes that falls outside the range of 2xx cause this function to trigger

不幸的是,我们正在调用一个非 RESTful API,该 API 可能会返回 200,并且正文中包含错误代码,我们需要重试。

我们尝试在 axios-retry 之前添加一个 Axios 拦截器,并在这种情况下更改结果状态;但这并没有触发后续的拦截器错误回调。

所做的工作是指定自定义适配器。然而,这并没有很好的记录,我们的代码也不能处理所有情况。

代码

const axios = require('axios');
const httpAdapter = require('axios/lib/adapters/http');
const settle = require('axios/lib/core/settle');
const axiosRetry = require('axios-retry');

const myAdapter = async function(config) {
  return new Promise((resolve, reject) => {
    // Delegate to default http adapter
    return httpAdapter(config).then(result => {
      // We would have more logic here in the production code
      if (result.status === 200) result.status = 500;
      settle(resolve, reject, result);
      return result;
    });
  });
}

const axios2 = axios.create({
  adapter: myAdapter
});

function isErr(error) {
  console.log('retry checking response', error.response.status);
  return !error.response || (error.response.status === 500);
}

axiosRetry(axios2, {
  retries: 3,
  retryCondition: isErr
});

// httpstat.us can return various status codes for testing
axios2.get('http://httpstat.us/200')
  .then(result => {
    console.log('Result:', result.data);
  })
  .catch(e => console.error('Service returned', e.message));

这适用于错误情况,打印:

retry checking response 500
retry checking response 500
retry checking response 500
retry checking response 500
Service returned Request failed with status code 500

它也适用于成功案例(将 URL 更改为 http://httpstat.us/201 ):

Result: { code: 201, description: 'Created' }

问题

将 URL 更改为 http://httpstat.us/404但是,结果是:

(node:19759) UnhandledPromiseRejectionWarning: Error: Request failed with status code 404
    at createError (.../node_modules/axios/lib/core/createError.js:16:15)
    at settle (.../node_modules/axios/lib/core/settle.js:18:12)

一个catch关于httpAdapter调用将捕获该错误,但我们如何将其传递到链中?

实现 Axios 适配器的正确方法是什么?

如果有更好的方法来处理这个问题(除了 fork axios-retry 库),这将是一个可以接受的答案。

更新

一位同事发现这样做 .catch(e => reject(e)) (或只是 .catch(reject) )在 httpAdapter 上调用似乎可以解决该问题。然而,我们仍然希望有一个实现包装默认 http 适配器的 Axios 适配器的规范示例。

最佳答案

这是有效的(在 Node 中):

const httpAdapter = require('axios/lib/adapters/http');
const settle = require('axios/lib/core/settle');

const customAdapter = config =>
  new Promise((resolve, reject) => {
    httpAdapter(config).then(response => {
      if (response.status === 200)
        // && response.data contains particular error
      {
        // log if desired
        response.status = 503;
      }
      settle(resolve, reject, response);
    }).catch(reject);
  });

// Then do axios.create() and pass { adapter: customAdapter }
// Now set up axios-retry and its retryCondition will be checked

关于node.js - 如何使用适配器更改 Axios 中的结果状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59401146/

相关文章:

javascript - axios 请求有express、node、ejs

javascript - 无法渲染父 Prop

jquery-mobile - jquery mobile 和 angular.js -> 可折叠似乎不起作用

c++ - 使用适配器设计模式

javascript - Nodejs 查找已知蓝牙设备

node.js - Mongodb findOne 与或

node.js - 在没有客户端嵌入 html 的情况下使用 socket.io

node.js - Nodejs 获取数据异步函数

javascript - 从 url 中删除查询字符串 - HashRouter

javascript - ember-model:如何强制从服务器重新获取记录?