Estoy escribiendo una secuencia asíncrona de varios pasos que involucra diferentes errores posibles en cada paso. Quiero abortar toda la secuencia si ocurre un error.
Estoy tratando de expresar esto como una secuencia lineal usando Promise.then() y Promise.catch() . Aquí está el pseudocódigo:
step1() .catch(errorAtStep1 => handlerErrorAtStep1) .then(resultOfStep1 => step2(resultOfStep1)) .catch(errorAtStep2 => handlerErrorAtStep2) .then(resultOfStep2 => step3(resultOfStep2)) ... Entiendo que necesito agregar algo en cada controlador de errores para evitar volver a las partes de then(result) . Sin embargo, cuando lanzo, la ejecución termina en el siguiente bloque catch(error) , que esperaba un error relacionado con su paso correspondiente, no esa otra cosa que lancé.
Mi pregunta es: ¿cuáles son las formas limpias de manejar esto, que minimizarían la distracción al leer el código?
Se me ocurrió esta clase:
class AbortChainError extends Error { static chain(handler) { return function(error) { if (error instanceof AbortChainError) throw error handler(error) throw new AbortChainError() } } } que permite escribir los bloques catch() como:
.catch(AbortChainError.chain(errorAtStep2 => handlerErrorAtStep2)) con la necesidad adicional de escribir un último bloque catch() vacío al final de la secuencia.
¿Podemos hacerlo mejor?
Si coloca esto en una función asíncrona, haría que los controladores de errores no devolvieran nada, y luego puede hacer cada paso uno por uno y ver si el resultado existe o no; si no es así, hubo un error , y puedes volver.
const doStuff = async () => { const r1 = await step1().catch(handlerErrorAtStep1); if (!r1) return; const r2 = await step2(r1).catch(handlerErrorAtStep2); if (!r2) return; // etcNo es el más SECO, pero creo que es el más fácil de entender.