uncaught then promises promesas multiple errors catch javascript exception promise

promises - then javascript



Cómo atrapar una excepción no capturada en Promise (5)

Actualización, las promesas nativas ahora hacen lo siguiente en la mayoría de los navegadores:

window.addEventListener("unhandledrejection", function(promiseRejectionEvent) { // handle error here, for example log });

Estábamos discutiendo esto el otro día.

Así es como harías esto con bluebird:

window.onpossiblyunhandledexception = function(){ window.onerror.apply(this, arguments); // call } window.onerror = function(err){ console.log(err); // logs all errors }

Con Bluebird también es posible usar Promise.onPossiblyUnhandledRejection . Las llamadas para done no son necesarias ya que la biblioteca detectará el rechazo no controlado a diferencia de Q (ACTUALIZACIÓN 2016: ahora escribí el código para Q y lo hace).

En cuanto a las promesas nativas , eventualmente informarán a window.onerror o a un nuevo controlador, pero el proceso de especificación aún no se ha completado; puede seguirlo aquí .

¿Hay alguna manera de detectar globalmente todas las excepciones, incluidas las excepciones de Promise? Ejemplo:

window.onerror = function myErrorHandler(errorMsg, url, lineNumber) { alert("Error occured: " + errorMsg);//or any message return false; } var myClass = function(){ } var pr = new Promise(function(resolve, react){ var myInstance = new myClass(); myInstance.undefinedFunction(); // this will throw Exception resolve(myInstance); }); pr.then(function(result){ console.log(result); }); // i know right will be this: // pr.then(function(result){ // console.log(result); // }).catch(function(e){ // console.log(e); // });

Este script morirá silenciosamente sin error. Nada en Firebug.

Mi pregunta es si cometo un error y olvidé detectarlo, ¿hay alguna forma de detectarlo globalmente?


En Node.js, puede usar:

process.on(''unhandledRejection'', (reason, promise) => { console.error(`Uncaught error in`, promise); });


La mayoría de las implementaciones prometedoras actualmente no proporcionan el tipo de funcionalidad a la que se refiere, pero una serie de bibliotecas prometedoras de terceros (que incluyen Q y bluebird ) proporcionan un método done() que detectará y arrojará cualquier error no detectado, lo que los generará a la consola

( Editar: vea la respuesta de Benjamin Gruenbaum sobre las características de Bluebird para manejar excepciones no capturadas)

Entonces, si tiene eso, solo debe seguir la regla general de que cualquier promesa que use debe devolverse o terminarse con .done() :

pr.then(function(result){ console.log(result); }) .done();

Para citar de la referencia Q API:

La regla de oro del uso done frente al uso es: return su promesa a otra persona o, si la cadena termina con usted, llame al done para finalizarla. Terminar con catch no es suficiente porque el controlador de catch puede generar un error.

Me doy cuenta de que esto todavía requiere un poco de trabajo extra y aún puede olvidarse de hacer esto, pero es una mejora sobre tener que .catch() y manejar explícitamente cada error, especialmente por la razón señalada anteriormente.


Si está escribiendo código que se puede ejecutar tanto en un navegador como en un entorno Node.js, puede envolver su código en una función de ejecución automática como esta:

var isNode = (typeof process !== ''undefined'' && typeof process.on !== ''undefined''); (function(on, unhandledRejection) { // PUT ANY CODE HERE on(unhandledRejection, function(error, promise) { console.error(`Uncaught error in`, promise); }); // PUT ANY CODE HERE })( isNode ? process.on.bind(process) : window.addEventListener.bind(window), isNode ? "unhandledRejection" : "unhandledrejection" );

¿Qué pasaría si usa este código?

  • Si lo ejecuta en un entorno Node.js, su controlador se adjuntará al objeto de proceso y se ejecutará cuando tenga una excepción no detectada en una promesa.

  • Si lo ejecuta en un entorno de navegador, su controlador se adjuntará al objeto de ventana y se ejecutará cuando tenga una excepción no detectada en una promesa y su navegador admita el evento de unhandledrejection .

  • Si lo ejecuta en un entorno de navegador sin soporte para el unhandledrejection , no podrá detectar su excepción unhandledrejection detectada y su unhandledrejection eventos de unhandledrejection controlado nunca se activará, pero no obtendrá ningún error si no hay excepciones no detectadas.


Si está utilizando Promise nativo, es bastante simple.
Solo necesita .catch este rechazo en algún lugar.

ajax(request).catch(function(rejected){ console.log(rejected); });

Si no lo atrapo en alguna parte, la promesa no alcanzada seguirá apareciendo. Pero si lo atrapo en alguna parte ...