Les exceptions dans les chaînes de promesses en JavaScript
Supposons que pour une raison quelconque notre promesse se termine par une erreur :
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('error');
}, 3000);
});
Dans ce cas, l'exécution du code passera immédiatement
au then qui contient une fonction de gestionnaire
d'erreur, ou au premier catch, selon
ce qui est rencontré en premier.
Voici un exemple de la première situation :
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
},
function(error) {
// l'exécution passera immédiatement ici
}
).then(
function(result) {
console.log(result);
}
);
Voici un exemple de la deuxième situation :
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// l'exécution passera immédiatement ici
}
).then(
function(result) {
console.log(result);
}
);
La fonction de gestionnaire a deux options d'action :
si elle a géré la situation exceptionnelle,
elle peut retourner un résultat via return
et l'exécution se poursuivra plus loin dans la chaîne.
Si elle n'a pas pu gérer l'erreur, elle peut
soit ne rien retourner, soit lever une exception
via throw. Dans ce cas, l'exécution
passera au gestionnaire d'erreur suivant
(dans then ou catch - selon ce qui est rencontré
en premier).
En règle générale, toutes les erreurs de la chaîne sont interceptées
à un seul endroit : un catch est placé
à la fin de la chaîne :
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// nous arriverons ici en cas d'erreur
}
);
Dans ce cas, l'exception peut survenir dans la promesse
elle-même, ou être levée via throw
dans n'importe quel maillon de la chaîne :
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
if (toutVaBien) {
return result + '2';
} else {
throw new Error('erreur'); // passer au gestionnaire le plus proche
}
}
)
.then(
function(result) {
return result + '3';
}
).catch(
function(error) {
// gestionnaire le plus proche
}
);
Notez que le catch est nécessaire précisément pour
le diagnostic de l'erreur : est-elle résoluble ou non.
Si l'erreur est résoluble, le catch doit
transmettre sa solution au then qui le suit.
Et si elle n'est pas résoluble (ou si ce catch
ne sait simplement pas comment la résoudre), alors nous devons
soit ne rien retourner, soit lever une exception :
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
if (erreurResoluble) {
return 'données'; // envoyer au then suivant
} else {
// ne rien retourner ou lever une exception
}
}
).then(
function(result) {
// ici nous résolvons l'erreur
}
);