2011-10-04 12 views
7

Tengo una herramienta, similar en formas a JSFiddle, que me permite escribir dinámicamente javascript y ejecutarlo en una página. El código puede ser líneas múltiples, y típicamente lo será.cargar código dinámicamente y obtener el número de línea del error de análisis

Desafortunadamente, si hay una excepción en el código que escribo, no puedo obtener el número de línea de la excepción si uso eval() para ejecutar el código.

he encontrado una solución parcial, que es en lugar de utilizar

try{ 
eval(code); 
} 
catch(e) { 
processException(e); 
} 

a su lugar hacer algo como esto:

var s = document.createElement('script'); 
s.appendChild(document.createTextNode(
    "try{\n" + 
    code + 
    "}catch(e){processException(e)}")); 
document.body.appendChild(s); 

Ahora, si el código se produce una excepción, y miro a la stack trace (en mi función processException()) Puedo obtener un número de línea de la excepción (en firefox y chrome, de todos modos).

Eso está muy bien si realmente es una excepción de tiempo de ejecución, como una variable no definida. El problema es si hay un error de análisis/sintaxis, como parens no coincidentes o similares. No consigo nada.

¿Hay alguna solución loca para esto, que funcione en Firefox y Chrome, como mínimo? ¿Evaluar dentro de eval dentro de la etiqueta de script dentro del objeto Function? Estoy intentando todo y no he encontrado nada que funcione.

Respuesta

2

Encontré finalmente una solución razonable.

Primero, ajusto window.onerror a alguna función. Esto no obtiene un seguimiento de pila completo, pero obtendrá un número de línea y archivo.

Entonces, hago esto:

var s = document.createElement('script'); 
s.appendChild(document.createTextNode(
    "var someUniqueGlobalName = function() {\n" + 
    code + 
    "\n};"; 
document.body.appendChild(s); 

Tenga en cuenta que esto no funciona realmente mi código, ya que simplemente crea una función (en el ámbito global, con el nombre 'someUniqueGlobalName' - que por supuesto Realmente me sale un nombre diferente cada vez que hago esto).

Si hay un error de sintaxis, quedará atrapado en la función window.onerror, y puedo obtener el tipo de error y el número de línea (que por supuesto tendré que restar, ya que agregué una línea al principio).

Ahora, desactivé window.onerror.

Finalmente, ejecuto el código llamando a unUniqueGlobalName() en un bloque try/catch. Aquí puedo obtener un seguimiento de pila completo con números de línea si hay un error de tiempo de ejecución.

+0

Este es un principio muy útil. Gracias. – SystemParadox

1

Usted podría tomar un paso más allá e integrar JSLint: https://github.com/douglascrockford/JSLint

Es bastante sencillo .. aquí está una prueba rápida ...

Descargar: https://raw.github.com/douglascrockford/JSLint/master/jslint.js

jshint_test.html:

<script type="text/javascript" src="jslint.js"></script> 
<script> 

var result = JSLINT("var some = true;\nif (some) {"); 

if (result) 
{ 
    alert('Looking good'); 
} 
else 
{ 
    var error_message = ''; 
    for (i in JSLINT.errors) 
    { 
    var error = JSLINT.errors[i]; 
    error_message += error.reason + ' on line: ' + error.line + ' character: ' + error.character + "\n"; 
    } 
    alert(error_message); 
} 
</script> 

Revise la documentación. El segundo argumento para JSLINT es un objeto de opciones ... hay TONELADAS de opciones.

+0

idea creativa, pero no lo que estoy buscando. – rob

+1

Curioso ... ¿qué estás buscando entonces? Esto le proporciona el análisis sintáctico y los errores de sintaxis que solicitó originalmente. – Jake

+0

Estoy buscando la corrección, no la opinión de Crockford sobre cómo debería ser JS. También es voluminoso para lo que estoy haciendo, por lo que preferiría navegador construido en la comprobación de sintaxis – rob

Cuestiones relacionadas