Sentry-javascript: ¿Registrar automáticamente todos los errores lanzados?

Creado en 10 feb. 2013  ·  31Comentarios  ·  Fuente: getsentry/sentry-javascript

¿Hay alguna manera de hacer que Raven registre todos los errores lanzados? Por alguna razón, registra algunas llamadas throw pero no otras. Descubrí que tiende a no registrar el comportamiento anidado más abajo en la pila de llamadas.

Comentario más útil

Aqui tienes:

var __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

window.Error = (function(_super) {

  __extends(_Class, _super);

  function _Class() {
    var error;
    error = _Class.__super__.constructor.apply(this, arguments);
    Raven.captureException(error);
    return error;
  }

  return _Class;

})(Error);

Todos 31 comentarios

jaja, el manejo de errores en Javascript es realmente terrible. ¿Puede darme un ejemplo de cómo está lanzando los errores?

Por ejemplo, lanzar una cadena no nos permite obtener ninguna información excepto el mensaje que se envió. Con un objeto Error real, podemos (intentar) obtener una pila.

Así que cuanta más información, mejor para esto.

Por supuesto.

Estoy lanzando un error así:

throw new Error("Error");

A veces inicia sesión como centinela ya veces no.

¿Está esto en una página que puedo echar un vistazo en alguna parte? ¿O puedes ponerlo en alguna parte? Honestamente, eso no es suficiente información. Hay alrededor de 10 factores que pueden explicar por qué un error no se registra, y la mayoría de ellos están fuera de nuestro alcance. :) Entonces, si puedo ver el contexto completo, puedo darte una sugerencia para ayudar al navegador.

La aplicación en realidad está escrita en CoffeeScript que se compila en JavaScript usando require.js. El punto de entrada principal se ve así:

Raven.config('http://[email protected]');
Raven.context(function() {
  define(['cs!csmain']);
});

También probé sin el envoltorio context y eso no pareció cambiar nada. Todavía registró throw llamadas que se hicieron más arriba en la pila de llamadas mientras ignoraba las de abajo.

Estás ejecutando Raven.install()

Y para require.js, si quisiera envolver módulos explícitamente, haría lo siguiente:

define(['module'], Raven.wrap(function(module) {
  // insert cool stuff here
}));

Lo olvidé en el fragmento, pero estoy llamando a install() después config()

No he intentado envolver módulos, pero pensé que si ya funciona en algunos lugares, ¿por qué no en otros?

Todo depende realmente de la pila de llamadas. Cuando las cosas comienzan a entrar en la tierra asíncrona, se pone difícil. Por ejemplo, esto no funcionaría como se esperaba:

Raven.context(function() {
  setTimeout(function() {
    throw new Error('crap');
  }, 1);
});

La función interna se ejecuta en su propio contexto fuera del contexto principal. Node.js resuelve esto con una cosa llamada "dominios", pero lamentablemente, esos no existen en la tierra de los navegadores.

Entonces, si un error no se detecta y se expande hasta la parte superior, generalmente se rechaza porque es 100% inútil en ese punto.

Ah, ya veo. ¿Quizás hay una manera de utilizar window.onerror ?

FWIW, si es posible, la forma más segura de capturar una excepción es usar explícitamente Raven.captureException . Entiendo que eso no siempre es factible, pero solo para tu información.

Entonces, un intento explícito ... excepto el bloque es el más confiable:

try {
  throw new Error('something');
} catch(e) {
  Raven.captureException(e);
}

Derecha. Por supuesto, sería genial capturar automáticamente los errores, pero JavaScript no hace que sea un juego fácil de jugar...

@pheuter No. :) Y esa es la parte divertida. Una vez que un error llega a window.onerror, ya no es un objeto Error real. Se aplana hasta convertirse en una cuerda inútil. Y también impone problemas de seguridad entre dominios. Entonces, básicamente, una vez que un error llega a window.onerror , generalmente se descarta ya que la única información que tenemos solo puede ser: "Script error." .

Apesta. Oh bueno, agradezco la aclaración!

No, Javascript no lo hace. Es realmente terrible, de hecho. :) Estoy investigando y explorando activamente formas de explotar el navegador para brindarnos mejor información. Incluso se me ha pasado por la cabeza la idea de monkey patch Function.prototype.call . Pero eso es probablemente muy malas noticias.

¡Totalmente! Si tiene alguna recomendación o sugerencia para aclarar la documentación, hágamelo saber. Siempre estoy buscando esas cosas.

Lo haré, los documentos de configuración y uso han sido bastante sencillos y fáciles de seguir.

Me pregunto si hay una forma de extender Error para que esto funcione.

@mattrobenolt , este es el enfoque que estamos tomando con CoffeeScript.

window.Error = class extends Error
  constructor: ->
    error = super
    Raven.captureException error
    return error

Entonces solo usa throw new Error "Test Error"

Comentario actualizado arriba para aclaración.

Mmm. Jugaré con esto el fin de semana. La última vez que lo intenté, no me dejaba parchear la ventana. Error. Lo intentaré de nuevo en más navegadores y veré qué es posible.

¡Gracias por el aviso!

Además, ¿puedes darme eso en Javascript normal? Estoy bastante seguro de lo que está haciendo, solo quiero volver a comprobarlo. Yo no escribo Coffeescript.

Aqui tienes:

var __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

window.Error = (function(_super) {

  __extends(_Class, _super);

  function _Class() {
    var error;
    error = _Class.__super__.constructor.apply(this, arguments);
    Raven.captureException(error);
    return error;
  }

  return _Class;

})(Error);

Ahora que lo pienso, este es un enfoque defectuoso. Simplemente anular el constructor hará que Raven capture todos los objetos de error, ya sea que se arrojen o no. :)

FYI, errorception encontró una manera de manejar esto. Sería genial si raven-js pudiera hacer lo mismo.

@dmcquay ¿Puede proporcionar un ejemplo que capture Errorception? Probablemente pueda aplicar ingeniería inversa.

De hecho, asumo que todos los controladores de errores JS son 50% raven.js;)

:caca:

@BYK , ¿alguna idea?

No tengo ningún conocimiento interno sobre errorception. Estoy usando el servicio y parece funcionar como se anuncia. Eso es todo lo que sé.

Inspeccioné cómo funcionan y parece que simplemente se adjuntan a window.onerror y no les importa el seguimiento de la pila. Al menos para este tipo de cosas.

Secuestrar el objeto Error funciona para Firefox, pero el punto de @mattrobenolt sobre capturarlos todos, incluso los que no se arrojan, es una preocupación válida.

Una solución sucia para esto podría ser almacenar las instancias Error creadas mediante el secuestro del constructor global y también escuchar onerror y comparar message , fileName y lineNo argumentos con las propiedades de los objetos Error almacenados. Si se encuentra una coincidencia, elimínela de la cola e informe.

Al evaluar todos los servicios de notificación de errores, noté que algunos servicios específicos de Javascript (como https://qbaka.com/) rastrean el seguimiento de la pila y muestran la acción del usuario que condujo a un error en particular. Lástima que errorception no haga eso, ya que parece superior en todos los demás aspectos.

Usaremos Sentry para nuestro código Django, y me topé con este problema mientras buscaba información sobre cómo funciona Sentry para Javascript. ¿La implementación actual de raven-js requiere que el código capture explícitamente todos los errores de JS y los informe a Sentry?

@ adityar7 No es así. Raven.js intenta lo mejor posible parchear e interceptar cosas si puede. En algunos casos más extremos, es posible que deba ajustar explícitamente, pero nos esforzamos mucho para que las cosas sucedan automáticamente.

@mattrobenolt Lo hizo funcionar arreglando algo de sintaxis. ¡Gracias!

¿Fue útil esta página
0 / 5 - 0 calificaciones