注意: 请不要将其标记为重复项。我已经看到许多有关尝试重试的axios帖子,但我还无法获得任何方法,包括内置的拦截器(意识到要打破v.18-> v.19)可以正常工作,而我我仍然卡住了。
由于竞争情况,我试图对API进行失败的调用以重试,因为在这种情况下,我需要一直调用该API直到成功,因为它最终总是会成功,但是如果系统创建的ID已经被调用,则会出错使用。
我创建了这个脚本来调试正在发生的事情。
const rax = require('retry-axios');
const axios = require('axios').default;
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
const retryErrorHandler = async (error) => {
console.log("Running retryErrorHandler");
const { config } = error;
if (!config || !config.retry) return Promise.reject(error);
config.__retryCount = config.__retryCount || 0;
if (config.__retryCount >= config.retry) {
console.log("...__retryCount is greater or equal to retry max....final reject");
// Reject with the error
return Promise.reject(error);
}
// Increase the retry count
config.__retryCount += 1;
// Create new promise to handle exponential backoff
await sleep(1500);
const instance = await axios(config);
instance.interceptors.response.use(response => response, error => retryErrorHandler(error));
return instance;
};
async function makeAxios(){
console.log('makeAxios');
const instance = await axios.create();
console.log('created');
instance.interceptors.response.use(response => response, error => retryErrorHandler(error));
return instance;
}
async function retryAxios(passedConfig, tries = 0) {
const maxTries = 10;
tries = +1;
console.log(`Retry #${tries} executing a ${passedConfig.method.toUpperCase()} for ${passedConfig.url}`);
try {
console.log('before trying to make call');
console.log({passedConfig});
const result = await axios(passedConfig);
console.log({ result });
return result;
} catch (error) {
console.log(`Retry #${tries} had an error: ${error}`);
console.log({error});
if (tries < maxTries) {
await sleep(Math.floor(Math.random() * 1500) + 750);
console.log(`Total tries: ${tries} is less than the max of ${maxTries}, trying again`);
axios(passedConfig);
}
}
}
async function makeAPICallMethod1(){
try{
console.log('started');
// # METHOD 1 - attaching to global axios with defaults - CLOSEST TO WORKING
const interceptorId = rax.attach();
console.log({interceptorId});
let response = await axios.put('https://httpstat.us/500');
console.log({response});
} catch (error) {
console.log('Caught an error');
console.log(error);
}
}
async function makeAPICallMethod2(){
try{
console.log('started');
// # Method 2 - new instance, does not override defaults for retry, retryDelay, or onRetryAttempt
const axiosInstance = axios.create();
axiosInstance.defaults.raxConfig = {
instance: axiosInstance,
retry: 10,
retryDelay: 750,
onRetryAttempt: err => {
const cfg = rax.getConfig(err);
console.log(`Retry attempt #${cfg.currentRetryAttempt}`);
}
};
const interceptorId = rax.attach(axiosInstance);
console.log({interceptorId});
const res = await axiosInstance.put('https://httpstat.us/500');
} catch (error) {
console.log('Caught an error');
console.log(error);
}
}
async function makeAPICallMethod3(){
try{
console.log('started');
// # Method 3 - config can be assigned but doesn't proceed past 1st retry.
const anotherAxios = await makeAxios();
let response = await anotherAxios.put('https://httpstat.us/500', null, { retry: 10, retryDelay: 1000 });
} catch (error) {
console.log('Caught an error');
console.log(error);
}
}
module.exports = {makeAPICallMethod2, makeAPICallMethod3};
// ===============
// node -p "require('./axios-test').makeAPICallMethod2()"
// node -p "require('./axios-test').makeAPICallMethod3()"
这两个实现中,当它们的重试设置都超过第一次时,它们都会在第一次执行后停止。
为什么不进行重试?
对于方法2:
started { interceptorId: 0 } Promise { <pending> } Caught an error
对于方法3:
started makeAxios Promise { <pending> } created Running retryErrorHandler
Caught an error Error: Request failed with status code 500