try then promises node handling error catch javascript node.js try-catch promise bluebird

javascript - then - Bluebird promete y captura ramificación



try catch promise js (1)

Me pregunto si hay una forma en que Bluebird prometa .catch un error lanzado y luego procesar algunas acciones específicas sin ramificación (promesa anidada).

Digamos que tengo

doSomethingAsync() .then(function (result) { if (!result) throw new CustomError(''Blah Blah''); if (result == 0) throw new CustomError2(''Blah Blah Blah''); return result; }) .then(function (result) { console.log(''Success, great!''); }) .catch(CustomError, function (error) { // Oh CustomError! return saveSomethingAsync(); }) .then(function (saved) { // Should only be executed if an CustomError has been thrown console.log("Let''s try again"); return doSomethingAsync(); }) .catch(CustomError2, function (error) { // Oh CustomError2! }) .delay(15000) // Don''t try again now ! .then(function () { // Should only be executed if an CustomError2 has been thrown console.log("Let''s try again after some long delay"); return doSomethingAsync(); }) .catch(function (error) { // Should catch all random errors of the chain })

Cuando ejecuto este código, obtengo varios comportamientos:

  • Si no se produce ningún error, obtengo "¡Éxito, genial!" y comienza de nuevo con "Probemos de nuevo después de un largo retraso"
  • Si CustomError lanza, obtengo "Probemos de nuevo"
  • Si CustomError2 arroja, obtengo "Probemos de nuevo después de un largo retraso"

No puedo entender qué está pasando con este flujo. Sería genial escribir algo como esto en lugar de anidar el código específico de los errores en las nuevas cadenas de promesas.


.catch un error lanzado y luego procesar algunas acciones específicas sin ramificar

No. Porque eso es una bifurcación. Anidar es totalmente natural aquí. Incluso podrías pensar en esto usando la metáfora de try-catch sincrónica y sería lo mismo.

No puedo entender qué está pasando con este flujo.

  • Si no se produce ningún error, obtengo "¡Correcto, genial!" y comienza de nuevo con "Probemos de nuevo después de un largo retraso"

Hm, eso es extraño, porque el "Probemos de nuevo" (sin demora) está encadenado antes de eso. Eventualmente deberías obtener ambos registros. Su cadena se procesa secuencialmente:

doSomethingAsync() // returns a result then return result // first callback: continues with it then console.log(''Success, great!'') // next callback: logs something catch // is ignored because no rejection then console.log("Let''s try again"); // next callback: logs something return doSomethingAsync(); // and returns a result catch // that result, not being a rejection, is ignored here delay // fulfillment is delayed then console.log("Let''s try again after some long delay"); // next callback again logs return doSomethingAsync(); // and returns a result catch // is ignored again

  • Si se lanza un CustomError, obtengo "Let''s try again"

Sí, porque saveSomethingAsync(); , se cumple el resultado de la promesa anterior, por lo que se .then() la siguiente .then() devolución de llamada en la cadena.

  • Si se lanza un CustomError2, aparece "Probemos de nuevo después de un largo retraso"

Sí, porque el error borró todo el camino hasta .catch(CustomError2, …) donde finalmente se manejó. En su camino, no se ejecutaron callbacks. Después de que se manejó el error , se cumple la promesa, y el siguiente .then() en la cadena llama a su devolución de llamada.

Creo que lo que realmente quieres aquí es

doSomethingAsync() .then(function(result) { if (!result) // CustomError(''Blah Blah''); // Oh CustomError! return saveSomethingAsync(); .then(function(saved) { console.log("Let''s try again"); return doSomethingAsync(); }); else if (result == 0) // CustomError2(''Blah Blah Blah''); // Oh CustomError2! return Promise.delay(15000) // Don''t try again now ! .then(function() { console.log("Let''s try again after some long delay"); return doSomethingAsync(); }) else console.log(''Success, great!''); // return undefined implied }).catch(function (error) { // does catch all random errors of the chain // thrown by any of the doSomethingAsync() or of the saveSomethingAsync })