λλλ‘ ECONNRESET
λ°ννλ APIκ° νλ μμ΅λλ€. κ·Έλμ λλ κ·Έλ¬ν μ€λ₯μ λν΄ λ€μ μλνκ³ μΆμ΅λλ€. μ΄ λΌμ΄λΈλ¬λ¦¬μ retry
κΈ°λ₯μ μΆκ°ν κ³νμ΄ μμ΅λκΉ?
μ΄κ²μ λν μ΄λ€ μ λ°μ΄νΈ?
μ λ μ΄κ²μ΄ λ§€μ° μ€μνλ€κ³ μκ°ν©λλ€. μλ리μ€λ μ°λ¦¬κ° λͺ¨λ°μΌ μΉμ© Axiosλ₯Ό ꡬνν λ μ¬μ©μκ° μΈν°λ· μμ€λ₯Ό WiFiμμ λͺ¨λ μ’ λ₯μ λͺ¨λ°μΌ μ°κ²°λ‘ μ νν μ μμ΅λλ€.
λλ μ΄λ° μ’ λ₯μ κΈ°λ₯μ΄ μ΄ λΌμ΄λΈλ¬λ¦¬μ μμ΄μλ μ λλ€κ³ μκ°ν©λλ€. νμν κ²½μ° μ΄λ₯Ό μν μΈν°μ ν°λ₯Ό λ§λ€ μ μμ΅λλ€.
@jtangelder μ΄λ€ μμ΄λμ΄κ° μ΄λ»κ² μκ²Όμ΅λκΉ?
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 μ΄ μμ κ° λ μ°ΎκΈ° μ¬μ μΌλ©΄ μ’κ² μ΅λλ€!
@jtangelder μ€ λν«μ μ£Όμ μ κ°μ¬ν©λλ€.
μ€ λν«μ μ½κ° μμ νλ©΄ λ°ν λ μ€λ₯ μνκ° 500 λμ 504κ°λμ΄μΌνλ€κ³ μκ°ν©λλ€.
@jtangelder λ§€μ° μ μ©ν μμ λλ€.
μ§μ λ°±μ€νλ‘ μμ
μ μννλ λ°©λ²μ λν μμ΄λμ΄κ° μλμ§ κΆκΈν©λλ€. 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 AxiosRequestConfig μ retry λ° retryDelay κ΅¬μ± μ΅μ μ μΆκ°νλ €κ³ μλνμ§λ§ μ‘΄μ¬νμ§ μλ κ² κ°μ΅λλ€. μ΄λ»κ² μλμν€μ ¨λμ?
@lawloretienne μ¬μλ 맀κ°λ³μλ₯Ό μ¬μ©νκΈ° μ μ λ΄ μμ μ μ½λλ₯Ό μΆκ°νλμ§ νμΈν΄μΌ ν©λλ€. νλ¬κ·ΈμΈμ²λΌ μλνκΈ° λλ¬Έμ μ μμ±μ axios μ체μ μΌλΆλ‘ λ¬Έμνλμ§ μμ΅λλ€.
config.__retryCount = config.__retryCount || 0;
@KyleRoss κ΅¬μ± κ΅¬μ±μ μ λ¬ν μ μμ΅λλ€. κ° '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).μ΄λ μμ μμ μμ μμ μ΄κ²μ μ’ λ κ΅¬μ± κ°λ₯νκ² λ§λ€ μ μμ΅λλ€.