J'ai une API qui renvoie de temps en temps ECONNRESET
. J'aimerais donc réessayer sur une telle erreur. Prévoyez-vous d'ajouter la fonctionnalité retry
à cette bibliothèque ?
Une mise à jour pour ceci?
Je pense que c'est très important. Le scénario peut-être que lorsque nous implémentons Axios pour le Web mobile, l'utilisateur bascule alors la source Internet du WiFi vers n'importe quel type de connexion mobile.
Je ne pense pas que ce genre de fonctionnalité devrait être dans cette bibliothèque. Si vous en avez besoin, vous pouvez créer un intercepteur pour cela.
@jtangelder des idées à quoi cela devrait-il ressembler ?
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);
Quelque chose comme ça! Il réessaye 500 erreurs une fois.
Je suis d'accord avec @jtangelder pour
@jtangelder @mzabriskie merci ! en fait, c'est aussi un excellent exemple pour la documentation
+1 J'aimerais que cet exemple soit plus facile à trouver !
@jtangelder merci beaucoup pour l'extrait
Une petite correction sur le snippet, je pense que le statut d'erreur renvoyé devrait être 504 au lieu de 500.
@jtangelder exemple très utile.
Je me demande, avez-vous des idées sur la façon de faire quelque chose avec un ralentissement exponentiel ? Est-il possible de retourner une promesse de retryFailedRequest
? Ou d'autres suggestions ? Merci!
L'exemple dans @jtangelder doit être inclus dans la page du livre de recettes
Vous pouvez maintenant utiliser axios-retry pour cela.
Je suis d'accord. Cela devrait vraiment faire partie de la bibliothèque, ou du moins être mieux documenté.
@mericsson J'ai trop besoin d'un ralentissement exponentiel lors de la nouvelle tentative. J'ai rassemblé ce qui suit qui fonctionne très bien. Vous pouvez ajouter la vérification des erreurs/codes d'état spécifiques, car cela ne fait actuellement qu'intercepter et réessayer toutes les erreurs.
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);
});
});
Utiliser:
axios.get('/some/endpoint', { retry: 5, retryDelay: 1000 })
.then(function(res) {
console.log('success', res.data);
})
.catch(function(err) {
console.log('failed', err);
});
Options de configuration :
retry
- Nombre de fois où réessayer la demande après la première demande ayant échoué.
retryDelay
- Nombre de millisecondes à attendre entre les requêtes échouées (valeur par défaut à 1).
Je peux rendre cela un peu plus configurable dans l'essentiel à un moment donné.
@KyleRoss Merci pour le code, j'ai fait un ajustement pour que les tentatives soient exponentielles
// 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 Merci pour le partage.
Le délai peut être réglé de plus en plus :
const RETRY_TIMEOUTS = [1, 3, 5, 10]; // seconds
const delay = RETRY_TIMEOUTS[config.retryCount] * 1000;
Si vous souhaitez réessayer une requête 4xx ou 5xx, vous devez travailler avec l'objet d'erreur comme ceci :
Pour intercepter vos demandes :
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);
});
Pour intercepter vos réponses :
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
Des idées géniales. J'ai rassemblé une bonne partie de cela dans un module npm, si les gens sont intéressés :
https://github.com/JustinBeckwith/retry-axios
Heureux de répondre aux demandes de fonctionnalités ✨
axios-retry
vs retry-axios
@KyleRoss J'ai essayé d'ajouter les options de configuration retry et retryDelay à AxiosRequestConfig mais il ne semble pas qu'elles existent. Comment as-tu fait pour que ça marche ?
@lawloretienne vous devez vous assurer d'ajouter le code dans mon exemple avant d'utiliser l'un des paramètres de nouvelle tentative. Puisqu'il agit plus comme un plugin, les nouvelles propriétés ne sont pas documentées dans le cadre d'axios lui-même.
config.__retryCount = config.__retryCount || 0;
@KyleRoss Impossible de transmettre la configuration de configuration, chaque 'config.__reyCount' est indéfini.
https://github.com/axios/axios/blob/v0.19.0/lib/core/mergeConfig.js
Les propriétés personnalisées sont désormais filtrées.
La configuration personnalisée de
axios.defaults.headers.common['retry'] = 3
axios.defaults.headers.common['retryDelay'] = 1000
axios.defaults.headers.common['retryCount'] = 0
@mericsson J'ai trop besoin d'un ralentissement exponentiel lors de la nouvelle tentative. J'ai rassemblé ce qui suit qui fonctionne très bien. Vous pouvez ajouter la vérification des erreurs/codes d'état spécifiques, car cela ne fait actuellement qu'intercepter et réessayer toutes les erreurs.
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); }); });
Utiliser:
axios.get('/some/endpoint', { retry: 5, retryDelay: 1000 }) .then(function(res) { console.log('success', res.data); }) .catch(function(err) { console.log('failed', err); });
Options de configuration :
retry
- Nombre de fois où réessayer la demande après la première demande ayant échoué.
retryDelay
- Nombre de millisecondes à attendre entre les requêtes échouées (valeur par défaut à 1).Je peux rendre cela un peu plus configurable dans l'essentiel à un moment donné.
Merci pour l'aide!
Commentaire le plus utile
@mericsson J'ai trop besoin d'un ralentissement exponentiel lors de la nouvelle tentative. J'ai rassemblé ce qui suit qui fonctionne très bien. Vous pouvez ajouter la vérification des erreurs/codes d'état spécifiques, car cela ne fait actuellement qu'intercepter et réessayer toutes les erreurs.
Utiliser:
Options de configuration :
retry
- Nombre de fois où réessayer la demande après la première demande ayant échoué.retryDelay
- Nombre de millisecondes à attendre entre les requêtes échouées (valeur par défaut à 1).Je peux rendre cela un peu plus configurable dans l'essentiel à un moment donné.