2010-10-15 10 views
16

Una cosa que me está volviendo loco es cómo Javascript falla silenciosamente en muchas situaciones diferentes.¿Hay alguna forma de evitar que Javascript falle silenciosamente?

(ejemplo removido porque confunde el punto de mi pregunta)

Muchas veces me he encontrado con un error que le dará un mensaje de error cuando se escribe en la consola de Firebug, pero cuando se ejecuta dentro de la secuencia de comandos página, falla silenciosamente, incluso con la consola Firebug activa y abierta.

Algunos de estos problemas pueden ser detectados por Crockford's JsLint, pero aún muchos no lo harán.

¿Hay alguna forma de habilitar más mensajes de error en el navegador?

¿Se puede hacer esto sin utilizar entornos de depuración de JavaScript? Creo que los depuradores no me ayudan mucho. Normalmente rocío unas pocas instrucciones console.log() y puedo localizar el problema en un minuto. Lo que me vuelve loco es que los errores silenciosos en Javascript pueden pasar desapercibidos durante mucho tiempo o aparecer de forma que no son nada obvios. Es aún más frustrante porque probar el enunciado en la consola NO DA un error, entonces, ¿qué está pasando?

He tenido el mismo problema con las excepciones por cierto, ¿alguien lo notó? Muchas veces mis declaraciones throw new no funcionan en absoluto. Pero si escribo lo mismo en la consola, lo hace.

Gracias por sus útiles comentarios (primeras respuestas), pero esa no es mi pregunta. Estas pruebas son útiles cuando necesita desinfectar parámetros en una clase, por ejemplo, cuando no está seguro del entorno. No desea probar la existencia de propiedades o clases donde esperan que estén allí; eso sería hinchar el código sin ninguna razón.

+0

¿Qué quiere decir con error silencioso? Cuando una página web se ejecuta en los navegadores, todos los errores de JavaScript son silenciosos de manera predeterminada, porque no hay motivo para mostrárselos a los visitantes del sitio. –

+1

Supongo que me pregunto qué están haciendo los gurús de Javascript de Yahoo y Google con esto. Tienen un gran compilador, y existe JsLint, pero no es suficiente. No puedo creer que estén aguantando esto. Debo estar perdiendo algo. Estoy tratando de averiguar si uno DEBE usar un entorno de depuración como el proporcionado por Microsoft, o si hay otros métodos para ejecutar el navegador en modo desarrollador y ver todos esos errores en la consola. ¿Y por qué Firebug permanece en silencio cuando se ejecuta la página, pero muestra errores cuando escribo el código ofensivo en la consola (con la consola siempre abierta)? –

Respuesta

6

Creo que algunas de las respuestas a esta pregunta están malinterpretando la pregunta. IIUC, la pregunta es que el error es siendo silenciado cuando este código se ejecuta dentro de una página web real, pero el OP no quiere. (Presumiblemente para fines de depuración, principalmente.)

Mi pregunta sería, ¿dónde está este código realmente ejecutándose en el contexto del sitio web? Lo más probable es que algo más esté sofocando el error antes de que llegue a ti. Por ejemplo, algunas bibliotecas pueden silenciar instintivamente los errores que se producen en devoluciones de llamada específicas (por ejemplo, para XHR). Sin embargo, si son buenos, también tienden a proporcionar un punto de enlace para recibir notificaciones si se produce un error.

+1

Tienes razón. Ahora que lo mencionas, creo que a veces he visto errores capturados por YUI (YUI 2.8). Tal vez están ejecutando una gran cantidad de código en los bloques de captura de prueba? Probaré la ejecución de mi código en un bloque try catch para ver qué sucede. –

4

Si está trabajando con objetos para los que no está seguro si es que existen en tiempo de ejecución o no, usted tiene que comprobar su existencia:

if (Foo && Foo.Apple) { 
    // exists, do something with it 
} else { 
    // doesn't exist, do Plan B 
} 

Tenga en cuenta que la expresión (Foo & & Foo.Apple) primero comprobará si existe Foo, y solo si lo hace, comprobará si tiene una propiedad llamada Apple. Si tiene, la rama if se ejecutará.

Si Foo no existe o si no contiene la propiedad Apple, se ejecutará la rama else.

+0

Tiene razón, pero este problema en particular fue que tenía un componente en mi "paquete" de javascript que no estaba cargado. El código no espera que ese componente no esté allí, es una dependencia. Mi pregunta es más sobre encontrar una manera de recibir un aviso en lugar de un error silencioso que a veces es tan frustrante. –

+0

Bueno, si tiene múltiples componentes, debe adoptar una postura defensiva y considerar la posibilidad de que un componente no se cargue/ejecute. Por supuesto, esperas que esté allí, pero no puedes estar seguro. Es por eso que programa a la defensiva y siempre primero verifica si el componente en particular existe usando la instrucción if. Si existe, multa, si no, use la rama else como un "aviso". Por supuesto, puede hacer uso de la rama else para intentar cargar el componente nuevamente (por ejemplo). –

5

El siguiente código se captura todos los errores en el bloque de catch:

var a; 
try { 
    a = new Foo.Apple(); 
} catch (err) { 
    // Error handling 
} 

Para más información: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch

+1

-1 para declarar una variable dentro de un bloque. Las declaraciones de declaración de variables deben ser las primeras declaraciones del contexto de ejecución. Declarar variables "en el medio del programa" es una mala práctica. –

+0

Además, creo que la verificación de existencia defensiva es una práctica mucho mejor que forzar errores. –

+1

Tiene razón sobre la declaración de la variable, la corrigió en el comentario. Sobre la verificación de existencia, si necesita saber específicamente qué declaración falló, tiene razón, pero en los casos en los que no importa y hay muchos controles, creo que es mucho mejor. – matte

3

acuerdo con @sime Vidas, si la excepción tiene que ser manejado y no dejarlo en silencio, primero use la condición booleana y verifique si el valor existe.

if(Foo.Apple){ 
\\your code 
} 
else 
{ 
//Foo.Apple does not exist, do some exception handling here 
} 
Cuestiones relacionadas