2012-07-31 22 views
8

Para informes de errores, me gustaría insertar un contenedor try-catch alrededor del código de cada función que tengo.¿Hay alguna manera de agregar try-catch a cada función en Javascript?

Así que, básicamente quiero reemplazar

function foo(arg){ 
    bar(); 
} 

... ... con

function foo(arg){ 
    try { 
     bar() 
    } 
    catch(e){ 
     customErrorHandler(e) 
    } 
} 

¿Hay una manera de aplicar esta cosa try-catch genérica a todas las funciones sin necesidad de editar manualmente todos ¿de ellos? Por ejemplo, modificando el prototipo del objeto Function?

EDITAR

¿Por qué quiero try-catch todas mis funciones: Estoy construyendo una aplicación HTML5 que estoy publicando en iOS y Android. Puedo ver por mi rudimentario error de javascript actual que, aunque la aplicación funciona bien en mi propio dispositivo, se producen errores en algunos otros dispositivos.

Mi objetivo es doble: cada vez que se produce un error de JavaScript en el dispositivo de alguien ...

  1. Quiero notificar al usuario que la aplicación no funcione perfectamente
  2. Quiero saber más o menos donde el error ocurrió, así que sé dónde buscar el problema
+1

No, simplemente podría envolver la función * invocation * en un try-catch, pero no su contenido si la función no contiene un try-catch. Por lo que vale, cubrir tu código con declaraciones try-catch es una muy mala idea. Si hay un error, debe resolverlo, no permitir que ocurra, pero suprimirlo a través de try-catch. – Utkanos

+2

+1 por querer probar apropiadamente atrapar todas tus funciones. Sin embargo, creo que vas a tener que editarlos todos manualmente. – Limey

+1

Try-catch es muy caro. ¿Seguro que quieres hacer esto? ¿Cuál es el requisito? –

Respuesta

9

Esto no es simple ya que no hay forma de encontrar todas las funciones de JavaScript definidas en todas partes. Por ejemplo, cualquier enfoque de este tipo probablemente perdería funciones de devolución de llamada que están definidas en tiempo de ejecución.

Probablemente tampoco quiera ajustar todas las funciones porque eso incluiría las funciones del navegador y las funciones de las bibliotecas de JavaScript que ciertamente no desea envolver.

Un enfoque mucho mejor es, probablemente, para definir una función que se envuelve otra función:

var tcWrapper = function(f) { 
    return function() { 
     try { 
      f.apply(this, arguments); 
     } catch(e) { 
      customErrorHandler(e) 
     } 
    } 
} 

Ahora puede utilizar esta función para decorar cualquier cosa que desee.Envoltorio será más sencilla si utiliza espacios de nombres:

var NS = { f: function(...) { ... } } 

sólo hay que poner todas las funciones para envolver en un espacio de nombres especial y luego iterar sobre el espacio de nombres:

$.each(NS, function(i,n) { 
    var p = NS[n]; 
    if(typeof p === 'function') { 
     NS[n] = tcWrapper(p); 
    } 
}); 
+0

No todas las funciones querrán el mismo 'esto'. Es posible que desee ser consciente de qué 'este' está enviando. Por ejemplo, los controladores de eventos a veces obtienen el objetivo del evento o métodos de objeto. Sin embargo, puede recorrer las propiedades de los objetos y reemplazarlos por un getter (con Object.defineProperty) que los envuelve en una función en línea que podría corregirlos a un valor que no puede manipularse desde el exterior, así como también envolverlos. ellos en un bloque try catch. – nus

+0

@nus: No entiendo tu punto. Acabo de pasar 'esto' pero quizás lo estoy haciendo mal? Tal vez su información es demasiado compleja para un comentario. ¿Qué tal si nos muestra el código y los motivos en otra respuesta? –

+0

Lo siento, cometí un error al no poder ver aplicar solo se ejecuta cuando la función devuelta ya está asociada a NS. De alguna manera pensé que se llamaba en el contexto de tcpWrapper, en cuyo caso se habría arreglado el 'this' de tcpWrapper en cada función. – nus

1

bien, parece que he encontrado aquí: http://www.nczonline.net/blog/2009/04/28/javascript-error-handling-anti-pattern/

Básicamente, todas las funciones se reemplazan por un contenedor try-catch con la función original en la parte try.

+6

El título de la publicación del blog dice que es un antipatrón, es decir, posible pero desaconsejable. Depende de ti, pero realmente no creo que esta sea una buena idea. – Utkanos

+1

Las publicaciones del blog discuten antipatrones pero también muestran soluciones. –

-3

me pregunto (esto es pura especulación, así que no estoy seguro si esto funcionaría) se podría hacer algo como esto:

function callTryCatch(functionSignature) { 
    try { 
     eval(functionSignature); 
    } catch (e) { 
     customErrorHandler(e); 
    } 
} 

function entryPoint() { 
    callTryCatch(function() { 
     // do function logic 
    }); 
} 

Una vez más, esto es pura especulación y no he probado, pero si es aún posible, creo que la clave está en la declaración eval.

+3

Nunca use 'eval'; en su caso, 'apply()' hace lo que quiere. –

0

necesitaba ir a fortificar un cierto código, entonces escribí una función llamada fortify y la puse en un módulo de NPM. Es un trabajo en progreso, pero debería ayudar.

https://github.com/infinitered/over-armour

Bono: trabaja con funciones asíncronas. Comentarios de bienvenida

Cuestiones relacionadas