рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдПрдкреАрдЖрдИ рд╣реИ рдЬреЛ рд╕рдордп-рд╕рдордп рдкрд░ ECONNRESET
рд▓реМрдЯрд╛рддреА рд╣реИред рддреЛ рдореИрдВ рдРрд╕реА рддреНрд░реБрдЯрд┐ рдкрд░ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдХреНрдпрд╛ рдЖрдкрдХреА рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ retry
рд╕реБрд╡рд┐рдзрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рд╣реИ?
рдЗрд╕ рдкрд░ рдХрд┐рд╕реА рднреА рдЕрджреНрдпрддрди?
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдкрд░рд┐рджреГрд╢реНрдп рд╢рд╛рдпрдж рдЬрдм рд╣рдо рдореЛрдмрд╛рдЗрд▓ рд╡реЗрдм рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рд┐рдпреЛрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд╛рдИрдлрд╛рдИ рд╕реЗ рдЗрдВрдЯрд░рдиреЗрдЯ рд╕реНрд░реЛрдд рдХреЛ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдореЛрдмрд╛рдЗрд▓ рдХрдиреЗрдХреНрд╢рди рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред
рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдЕрдЧрд░ рдЖрдкрдХреЛ рдЗрд╕рдХреА рдЬрд░реВрд░рдд рд╣реИ рддреЛ рдЖрдк рдЗрд╕рдХреЗ рд▓рд┐рдП рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред
@jtangellder рдХреЛрдИ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП?
function retryFailedRequest (err) {
if (err.status === 500 && err.config && !err.config.__isRetryRequest) {
err.config.__isRetryRequest = true;
return axios(err.config);
}
throw err;
}
axios.interceptors.response.use(undefined, retryFailedRequest);
рдХреБрдЫ рдЗрд╕ рддрд░рд╣! рдпрд╣ рдПрдХ рдмрд╛рд░ 500 рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рдкреБрди: рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИред
рдореИрдВ @jtangelder рд╕реЗ рд╕рд╣рдордд
@jtangelder @mzabriskie рдзрдиреНрдпрд╡рд╛рдж! рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреЗ рд▓рд┐рдП рднреА рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИ
+1 рдореЗрд░реА рдЗрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЙрджрд╛рд╣рд░рдг рдвреВрдВрдврдирд╛ рдЖрд╕рд╛рди рд╣реЛ!
@jtangellder рд╕реНрдирд┐рдкреЗрдЯ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рдж
рд╕реНрдирд┐рдкреЗрдЯ рдкрд░ рдереЛрдбрд╝рд╛ рд╕реБрдзрд╛рд░, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд▓реМрдЯрд╛рдИ рдЧрдИ рддреНрд░реБрдЯрд┐ рд╕реНрдерд┐рддрд┐ 500 тАЛтАЛрдХреЗ рдмрдЬрд╛рдп 504 рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред
@jtangellder рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рдЙрджрд╛рд╣рд░рдгред
рдореИрдВ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВ, рдШрд╛рддреАрдп рдмреИрдХрдСрдл рдХреЗ рд╕рд╛рде рдХреБрдЫ рдХреИрд╕реЗ рдХрд░реЗрдВ рдЗрд╕ рдкрд░ рдХреЛрдИ рд╡рд┐рдЪрд╛рд░? рдХреНрдпрд╛ retryFailedRequest
рд╕реЗ рдХреЛрдИ рд╡рд╛рджрд╛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ? рдпрд╛ рдЕрдиреНрдп рд╕реБрдЭрд╛рд╡? рдзрдиреНрдпрд╡рд╛рдж!
@jtangelder рдореЗрдВ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдХреБрдХрдмреБрдХ рдкреЗрдЬ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП
рдЕрдм рдЖрдк рдЗрд╕рдХреЗ рд▓рд┐рдП axios-retry рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдореИрдВ рд╕рд╣рдордд рд╣реВрдВред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╛ рдХрдо рд╕реЗ рдХрдо рдмреЗрд╣рддрд░ рджрд╕реНрддрд╛рд╡реЗрдЬ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
@mericsson рдореБрдЭреЗ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╕рдордп рдШрд╛рддреАрдп
axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) {
var config = err.config;
// If config does not exist or the retry option is not set, reject
if(!config || !config.retry) return Promise.reject(err);
// Set the variable for keeping track of the retry count
config.__retryCount = config.__retryCount || 0;
// Check if we've maxed out the total number of retries
if(config.__retryCount >= config.retry) {
// Reject with the error
return Promise.reject(err);
}
// Increase the retry count
config.__retryCount += 1;
// Create new promise to handle exponential backoff
var backoff = new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, config.retryDelay || 1);
});
// Return the promise in which recalls axios to retry the request
return backoff.then(function() {
return axios(config);
});
});
рдХрд╛рдо рдореЗрдВ рд▓рд╛рдирд╛:
axios.get('/some/endpoint', { retry: 5, retryDelay: 1000 })
.then(function(res) {
console.log('success', res.data);
})
.catch(function(err) {
console.log('failed', err);
});
рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╡рд┐рдХрд▓реНрдк:
retry
- рдкрд╣рд▓реЗ рдЕрд╕рдлрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рдмрд╛рдж рдЕрдиреБрд░реЛрдз рдХреЛ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреА рд╕рдВрдЦреНрдпрд╛ред
retryDelay
- рд╡рд┐рдлрд▓ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдмреАрдЪ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреА рд╕рдВрдЦреНрдпрд╛ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ 1 рд╣реИ)ред
рдореИрдВ рдЗрд╕реЗ рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░ рдПрдХ рд╕рд╛рд░ рдореЗрдВ рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рдиреНрдпрд╛рд╕ рдпреЛрдЧреНрдп рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВред
@KyleRoss рдХреЛрдб рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореИрдВрдиреЗ рдкреБрдирд░реНрдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЗ рд▓рд┐рдП рдШрд╛рддреАрдп рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рдпреЛрдЬрди рдХрд┐рдпрд╛ рд╣реИ
// Create new promise to handle exponential backoff. formula (2^c - 1 / 2) * 1000(for mS to seconds)
const backOffDelay = config.retryDelay
? ( (1/2) * (Math.pow(2, config.__retryCount) - 1) ) * 1000
: 1;
const backoff = new Promise((resolve) => {
setTimeout(() => {
resolve();
}, backOffDelay);
});
@KyleRoss рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
рджреЗрд░реА рддреЗрдЬреА рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ:
const RETRY_TIMEOUTS = [1, 3, 5, 10]; // seconds
const delay = RETRY_TIMEOUTS[config.retryCount] * 1000;
рдпрджрд┐ рдЖрдк 4xx рдпрд╛ 5xx рдЕрдиреБрд░реЛрдз рдХрд╛ рдкреБрди: рдкреНрд░рдпрд╛рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рддреНрд░реБрдЯрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреИрд╕реЗ:
рдЖрдкрдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП:
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
рдЕрдкрдиреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
рд╢рд╛рдирджрд╛рд░ рд╡рд┐рдЪрд╛рд░ред рдпрджрд┐ рд▓реЛрдЧ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдореИрдВрдиреЗ рдЗрд╕реЗ npm рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдХрд╛рдлреА рд╣рдж рддрдХ рд░реЛрд▓ рдХрд┐рдпрд╛:
https://github.com/JustinBeckwith/retry-axios
рд╕реБрд╡рд┐рдзрд╛ рдЕрдиреБрд░реЛрдз рд▓реЗрдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реБрдИ
axios-retry
рдмрдирд╛рдо retry-axios
@KyleRoss рдореИрдВрдиреЗ
@lawloretienne рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдХреЛрдб рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдпрд╣ рдПрдХ рдкреНрд▓рдЧрдЗрди рдХреА рддрд░рд╣ рдЕрдзрд┐рдХ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рдирдП рдЧреБрдгреЛрдВ рдХреЛ рд╕реНрд╡рдпрдВ рдЕрдХреНрд╖ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд▓реЗрдЦрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
config.__retryCount = config.__retryCount || 0;
@KyleRoss config config рдкрд╛рд╕ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде, рдкреНрд░рддреНрдпреЗрдХ 'config.__reyCount' рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИред
https://github.com/axios/axios/blob/v0.19.0/lib/core/mergeConfig.js
рдХрд╕реНрдЯрдо рдЧреБрдг рдЕрдм рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░ рджрд┐рдП рдЧрдП рд╣реИрдВред
@dennisreimann рдХрд╕реНрдЯрдо рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЕрдм v0.19 рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЕрдм рд╣рдо рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
axios.defaults.headers.common['retry'] = 3
axios.defaults.headers.common['retryDelay'] = 1000
axios.defaults.headers.common['retryCount'] = 0
@mericsson рдореБрдЭреЗ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╕рдордп рдШрд╛рддреАрдп
axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) { var config = err.config; // If config does not exist or the retry option is not set, reject if(!config || !config.retry) return Promise.reject(err); // Set the variable for keeping track of the retry count config.__retryCount = config.__retryCount || 0; // Check if we've maxed out the total number of retries if(config.__retryCount >= config.retry) { // Reject with the error return Promise.reject(err); } // Increase the retry count config.__retryCount += 1; // Create new promise to handle exponential backoff var backoff = new Promise(function(resolve) { setTimeout(function() { resolve(); }, config.retryDelay || 1); }); // Return the promise in which recalls axios to retry the request return backoff.then(function() { return axios(config); }); });
рдХрд╛рдо рдореЗрдВ рд▓рд╛рдирд╛:
axios.get('/some/endpoint', { retry: 5, retryDelay: 1000 }) .then(function(res) { console.log('success', res.data); }) .catch(function(err) { console.log('failed', err); });
рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╡рд┐рдХрд▓реНрдк:
retry
- рдкрд╣рд▓реЗ рдЕрд╕рдлрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рдмрд╛рдж рдЕрдиреБрд░реЛрдз рдХреЛ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреА рд╕рдВрдЦреНрдпрд╛ред
retryDelay
- рд╡рд┐рдлрд▓ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдмреАрдЪ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреА рд╕рдВрдЦреНрдпрд╛ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ 1 рд╣реИ)редрдореИрдВ рдЗрд╕реЗ рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░ рдПрдХ рд╕рд╛рд░ рдореЗрдВ рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рдиреНрдпрд╛рд╕ рдпреЛрдЧреНрдп рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВред
рдорджрдж рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
@mericsson рдореБрдЭреЗ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╕рдордп рдШрд╛рддреАрдп
рдХрд╛рдо рдореЗрдВ рд▓рд╛рдирд╛:
рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╡рд┐рдХрд▓реНрдк:
retry
- рдкрд╣рд▓реЗ рдЕрд╕рдлрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рдмрд╛рдж рдЕрдиреБрд░реЛрдз рдХреЛ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреА рд╕рдВрдЦреНрдпрд╛редretryDelay
- рд╡рд┐рдлрд▓ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдмреАрдЪ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреА рд╕рдВрдЦреНрдпрд╛ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ 1 рд╣реИ)редрдореИрдВ рдЗрд╕реЗ рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░ рдПрдХ рд╕рд╛рд░ рдореЗрдВ рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рдиреНрдпрд╛рд╕ рдпреЛрдЧреНрдп рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВред