Eccezioni nelle catene di Promise in JavaScript
Supponiamo che per qualche motivo la nostra Promise venga rifiutata con un errore:
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('error');
}, 3000);
});
In questo caso, l'esecuzione salterà immediatamente
al then che contiene un gestore di errore,
o al primo catch incontrato, a seconda di quale
venga trovato prima.
Ecco un esempio del primo caso:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
},
function(error) {
// l'esecuzione salterà immediatamente qui
}
).then(
function(result) {
console.log(result);
}
);
Ecco un esempio del secondo caso:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// l'esecuzione salterà immediatamente qui
}
).then(
function(result) {
console.log(result);
}
);
Il gestore di errore ha due possibilità:
se riesce a gestire la situazione eccezionale,
può restituire un risultato tramite return
e l'esecuzione continuerà lungo la catena.
Se invece non riesce a gestire l'errore, può
o non restituire nulla, o lanciare un'eccezione
tramite throw. In questo caso, l'esecuzione
passerà al successivo gestore di errore
(in un then o catch - a seconda di quale
venga incontrato per primo).
Di solito, tutti gli errori della catena vengono gestiti
in un unico punto: un catch viene posizionato
alla fine della catena:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// arriveremo qui in caso di errore
}
);
L'eccezione può originare dalla Promise stessa,
oppure essere lanciata tramite throw
in qualsiasi anello della catena:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
if (tuttoOk) {
return result + '2';
} else {
throw new Error('errore'); // passiamo al gestore più vicino
}
}
)
.then(
function(result) {
return result + '3';
}
).catch(
function(error) {
// gestore più vicino
}
);
Tieni presente che catch serve proprio per
diagnosticare l'errore: è risolvibile o meno.
Se l'errore è risolvibile, il catch dovrebbe
passarne la soluzione al then successivo.
Se invece non è risolvibile (o questo specifico catch
non sa come risolverlo), allora dovremmo
o non restituire nulla o lanciare un'eccezione:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
if (erroreRisolvibile) {
return 'dati'; // inviamo al then successivo
} else {
// non restituiamo nulla o lanciamo un'eccezione
}
}
).then(
function(result) {
// qui risolviamo l'errore
}
);