我们正在使用axios-retry库,该库在内部使用以下代码:
axios.interceptors.response.use(null, error => {
由于它仅指定错误回调,因此Axios documentation说:
任何状态代码超出2xx范围都会触发此功能
不幸的是,我们正在调用一个非RESTful API,该API可以在主体中返回200并带有错误代码,我们需要重试。
我们已经尝试在axios-retry之前添加Axios拦截器,并在这种情况下更改结果状态。但这并不会触发后续的拦截器错误回调。
did 的工作是指定自定义适配器。但是,这没有充分的文档证明,我们的代码无法处理所有情况。
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适配器的正确方法是什么?
如果有更好的方法来解决这个问题(不使用axios-retry库,则可以接受)。
一位同事发现,在.catch(e => reject(e))
通话中执行.catch(reject)
(或仅httpAdapter
)似乎可以解决此问题。但是,我们仍然希望有一个规范的示例来实现一个包装了默认http适配器的Axios适配器。
答案 0 :(得分:1)
这是起作用的(在节点中):
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