javascript - sintomas - ¿Cómo puedo depurar mi código asincrónico basado en promesas si la biblioteca se está tragando todas las excepciones?
qué se siente cuando el cuerpo se está desintoxicando (3)
El problema
JSFiddle : http://jsfiddle.net/missingno/Gz8Pe/2/
Tengo un código que se ve así:
var d = new Deferred();
d.resolve(17);
return d.then(function(){
//do some stuff...
})
.then(function(){
var obj = a_funtion_that_returns_null_on_IE();
var x = obj.some_property; //BOOM!
});
El problema es que cuando estoy en IE, todo lo que puedo ver es ''obj'' is null or not an object
, sin ninguna referencia al número de línea correspondiente y sin que el depurador se detenga en la línea ofensiva (como desearía).
Este tipo de problema hace que sea difícil depurar el código y las únicas soluciones en las que puedo pensar en este momento (meterme con la biblioteca de flujo de control o recurrir a la depuración paso a paso con el depurador o console.log) son cosas que preferiría no tener que hacer.
Lo que creo que está sucediendo
Para permitir que se agreguen errbacks después de que se activa la cadena, then
tomarán de forma preventiva las excepciones lanzadas por las devoluciones de llamada. Creo que esta es la razón por la que el depurador de IE no se detiene en el error o muestra el mensaje de error habitual sin el número de línea.
Los mensajes de error sin los números de línea provienen de la biblioteca de flujo de control: proporciona un deferredOnError
que se invoca cada vez que se captura una excepción y se guarda para más adelante y el comportamiento predeterminado es el objeto console.error -ing the Error:
dojo.config.deferredOnError = function(err){
//a chance to log the exception after it is captured by "then"
//or do other things with it
console.error(err);
}
Lamentablemente, no pude encontrar la manera de obtener el número de línea o la pila del objeto de error en IE y el gancho se llama de una manera que no me permite volver a lanzar la excepción y dejar que suba hasta el nivel superior.
Lo que quiero
Quiero tener una mejor manera de depurar el código asíncrono y luego seguir con el depurador paso a paso. En el mejor de los casos, una forma de hacer que el depurador se detenga en las excepciones (como lo hace en las excepciones no controladas) o al menos en una forma de obtener números de línea o trazar rastros del objeto Error que se lanzó.
Lo que terminé haciendo
Agregué una función de secuencia a mi mini biblioteca de funciones auxiliares asíncronas. Básicamente ejecuta una secuencia de llamadas "entonces", excepto que agrega pasos intermedios adicionales para volver a lanzar cualquier excepción que termine siendo atrapada por los Diferidos. También acepta un controlador de error opcional para capturar las excepciones.
Cuando lo llamo, se ve así:
go([
function(){
return 17;
},
function(x){
//return some stuff
},
function(){
var obj = a_function_that_returns_null_on_IE();
var x = obj.some_property; //BOOM!
}
], function(){
//an optional error handler
});
Otra razón por la que hice las cosas de esta manera es porque tengo un montón de código que necesita funcionar simultáneamente con sincronización o código asíncrono (usando Deferred.when para hacer el encadenamiento). Usando mi función personalizada, permítanme usar una única sintaxis unificada y los errores que no se capturan en el caso asíncrono son consistentes con el caso de sincronización, donde no hay diferidos involucrados. También creo que está bien no capturar el error, ya que a diferencia del caso general, cuando uso "ir" sé a priori cómo se llamará el código, por lo que no hay necesidad de capturar excepciones para alguien que necesite atrapar ellos en el futuro.
Además, el uso de una solución personalizada me dio la libertad de aplicar algunas preferencias de diseño personal :)
Además de eso, terminé reduciendo la cantidad de excepciones que genero a través de la base de códigos. La administración de excepciones en el código asíncrono es más molesto de lo habitual y, en ocasiones, es más sencillo simplemente retroceder en el manejo de las condiciones de error devolviendo un nulo o un código de error.
Además, nos aseguramos de que las excepciones que creamos nosotros mismos sean instancias de la clase de error incorporada, intead de otros objetos. La razón es que la clase de error incorporada registra el número de línea y el rastro de la pila donde se generó en una especie de navegador cruzado.
Esto funciona con cualquier marco sin configuración previa y todos los navegadores recientes lo admiten.
Pause On Caught Exceptions: Esto realmente detendrá la ejecución de javascript y te llevará exactamente donde está el código problemático, mientras está sucediendo.
En Chrome:
- Herramientas de desarrollo ,
- Pestaña Fuentes ,
- Haga una pausa en las excepciones (icono similar a una parada) y luego
- la casilla de verificación Pausa en excepciones atrapadas
Solución 2016
Si está utilizando ES Promises nativas, no haga absolutamente nada; Chrome informa automáticamente rechazos de promesa no capturados en la consola.
Observe cómo el capturado ( Second fail
) no muestra nada, pero el rechazo no detectado aparece en la consola después de que el código se ejecuta.