2009-06-17 8 views
17

Estoy intentando crear una infraestructura de registro de errores de JavaScript.window.onerror no se activa en Firefox

Estoy tratando de establecer window.onerror para ser mi controlador de errores. Funciona en IE 6, pero cuando lo ejecuto en Firefox, se ejecuta en algún método conflictivo onerror.

var debug = true; 

MySite.Namespace.ErrorLogger.prototype = { 

    //My error handling function. 
    //If it's not in debug mode, I should get an alert telling me the error. 
    //If it is, give a different alert, and let the browser handle the error. 
    onError: function(msg, url, lineNo) { 
     alert('onError: ' + msg); 
     if (!debug) { 
      alert('not debug mode'); 
      return true; 
     } 
     else { 
      alert(msg); 
      return false; 
     } 
    } 
} 

//Document ready handler (jQuery shorthand) 
$(function() { 
    log = $create(MySite.Namespace.ErrorLogger); 

    window.onerror = log.onError; 

    $(window).error(function(msg, url, line) { 
     log.onError(msg, url, line); 
    }); 
}); 

Si uso setTimeout("eval('a')", 1); donde 'a' es una variable no definida, mi gestor de errores es lo que se disparó (funciona). Sin embargo, mi registrador de errores necesita detectar todos los errores lanzados por los clientes que acceden al sitio web, no solo el código incorrecto en un solo lugar.

El código está en una página .js a la que se llama desde la página base (C#) de un sitio web. El sitio también usa jQuery, así que tengo una función que anula la función jQuery bind, y esa función funciona bien en Firefox 3 e IE 6.

Sé que Firefox está viendo el error porque aparece tanto en el Error Console y Firebug, pero mi funciónwindow.onerror aún no se está llamando.

¿Alguna idea sobre cómo anular lo que Firefox está haciendo?

+2

Alguien más en mi grupo se hizo cargo de este proyecto y cambió por completo todo lo que estaba haciendo, así que nunca sabré lo que estaba mal. –

Respuesta

23

El siguiente es probado y funciona en IE 6 y Firefox 3.0.11:

<html> 
<head> 
<title>Title</title> 
</head> 
<body> 
    <script type="text/javascript"> 
    window.onerror = function (msg, url, num) { 
     alert(msg + ';' + url + ';' + num); 
     return true; 
    } 
    </script> 
    <div> 
    ...content... 
    </div> 
    <script type="text/javascript"> 
    blah; 
    </script> 
</body> 
</html> 

Si alguna otra librería JavaScript que va a cargar también se adhiera a window.onerror usted puede hacer esto:

<script type="text/javascript"> 
function addHandler(obj, evnt, handler) { 
    if (obj.addEventListener) { 
     obj.addEventListener(evnt.replace(/^on/, ''), handler, false); 
    // Note: attachEvent fires handlers in the reverse order they 
    // were attached. This is the opposite of what addEventListener 
    // and manual attachment do. 
    //} else if (obj.attachEvent) { 
    // obj.attachEvent(evnt, handler); 
    } else { 
     if (obj[evnt]) { 
      var origHandler = obj[evnt]; 
      obj[evnt] = function(evt) { 
       origHandler(evt); 
       handler(evt); 
      } 
     } else { 
      obj[evnt] = function(evt) { 
       handler(evt); 
      } 
     } 
    } 
} 
addHandler(window, 'onerror', function (msg, url, num) { 
    alert(msg + ';' + url + ';' + num); 
    return true; 
}); 
addHandler(window, 'onerror', function (msg, url, num) { 
    alert('and again ' + msg + ';' + url + ';' + num); 
    return true; 
}); 
</script> 

Lo anterior le permite conectar tantos manejadores onerror como desee. Si ya existe un controlador personalizado onerror, lo invocará, luego el suyo.

Tenga en cuenta que addHandler() se puede utilizar para unir varios controladores a cualquier acontecimiento:

addHandler(window, 'onload', function() { alert('one'); }); 
addHandler(window, 'onload', function() { alert('two'); }); 
addHandler(window, 'onload', function() { alert('three'); }); 

Este código es nuevo y algo experimental. No estoy 100% seguro de que addEventListener hace exactamente lo que hace el archivo adjunto manual, y como se comentó, attachEvent dispara los controladores en el orden inverso al que estaban adjuntos (por lo que vería 'tres, dos, uno' en el ejemplo anterior). Si bien no necesariamente es "incorrecto" o "incorrecto", es lo opuesto a lo que hace el otro código en addHandler y, como resultado, podría dar lugar a un comportamiento incoherente entre el navegador y el navegador, por lo que lo eliminé.

EDIT:

Este es un caso de prueba completa para demostrar el evento onerror:

<html> 
<head> 
<title>Title</title> 
</head> 
<body> 
<script type="text/javascript"> 
function addHandler(obj, evnt, handler) { 
    if (obj.addEventListener) { 
     obj.addEventListener(evnt.replace(/^on/, ''), handler, false); 
    } else { 
     if (obj[evnt]) { 
      var origHandler = obj[evnt]; 
      obj[evnt] = function(evt) { 
       origHandler(evt); 
       handler(evt); 
      } 
     } else { 
      obj[evnt] = function(evt) { 
       handler(evt); 
      } 
     } 
    } 
} 
addHandler(window, 'onerror', function (msg, url, num) { 
    alert(msg + ';' + url + ';' + num); 
    return true; 
}); 
</script> 
<div> 
...content... 
</div> 
<script type="text/javascript"> 
blah; 
</script> 
</body> 
</html> 

Cuando el código anterior se pone en test.htm y se carga en Internet Explorer desde los idks locales, se debería ver un cuadro de diálogo que dice 'blah' is undefined;undefined;undefined.

Cuando el código anterior se pone en test.htm y se carga en Firefox 3.0.11 (y los últimos 3.5 a partir de esta edición - Gecko/20090616) desde el disco local, debería ver un cuadro de diálogo que dice [object Event];undefined;undefined. Si eso no está sucediendo, tu copia de Firefox no está configurada correctamente o rota de algún otro modo. Todo lo que puedo sugerir es que elimines Firefox, elimines tus perfiles locales (la información sobre cómo encontrar tu perfil está disponible here) y vuelves a instalar la última versión y vuelves a probar.

+0

La sentencia if es lo que se activa en los eventos que quiero que maneje mi registrador de errores en Firefox. ¿Cuál es la relevancia del addEventListener que se creó en esa declaración if? –

+0

Lo único que ocurre con esto es que cada vez que abro Firefox, lo que pongo en la instrucción "if" se activa. Sin embargo, no es una reacción a mi error. –

+0

addHandler() es una forma genérica de agregar múltiples funciones de manejador a un evento. El if (obj.addEventListener) prueba para ver si el navegador admite el método addEventListener() en el objeto, si lo hace, agrega un controlador mediante el método integrado compatible con el navegador. Si el navegador no es compatible con el método addEventListener(), encadena a su nuevo controlador detrás del último controlador agregado. –

7

Recuerde devolver true desde cualquier window.onerror handler personalizado, o firefox se encargará de todos modos.

2

Parece que hay un error abierto (# 3982) en jQuery 1.3.x - jQuery.error event gets incorrect arguments. La última actualización hace 2 meses con el comentario:

Teniendo en cuenta lo loco que el evento de error es, y con qué frecuencia se utiliza, estoy de acuerdo que es más fácil de eliminar el soporte por ello. He agregado una nota a los documentos ya que no funciona de todos modos.

Supongo que simplemente pondré window.onerror, similar a lo que publicó Grant. Además, FireFox: addEventListener Vs. window.onerror menciona que "element.addEventListener", causando un error no activa "window.onerror".

Cuestiones relacionadas