Sentry-javascript: Enregistrer automatiquement toutes les erreurs générées ?

Créé le 10 févr. 2013  ·  31Commentaires  ·  Source: getsentry/sentry-javascript

Existe-t-il un moyen pour que Raven enregistre toutes les erreurs générées ? Pour une raison quelconque, il enregistre certains appels throw mais pas d'autres. J'ai constaté qu'il avait tendance à ne pas enregistrer les comportements imbriqués plus bas dans la pile des appels.

Commentaire le plus utile

Voici:

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);

Tous les 31 commentaires

haha, la gestion des erreurs en Javascript est vraiment terrible. Pouvez-vous me donner un exemple de la façon dont vous lancez les erreurs ?

Par exemple, lancer une chaîne ne nous permet pas d'obtenir d'informations à l'exception du message qui a été envoyé. Avec un objet réel Error , nous pouvons (tenter) d'obtenir une pile.

Donc, plus il y a d'informations, mieux c'est.

En effet.

Je lance une erreur comme ceci:

throw new Error("Error");

Parfois, il se connecte à la sentinelle et parfois non.

Est-ce sur une page que je peux consulter quelque part ? Ou pouvez-vous le mettre quelque part? Honnêtement, ce n'est tout simplement pas assez d'informations. Il y a environ 10 facteurs qui peuvent expliquer pourquoi une erreur n'est pas enregistrée, et la plupart d'entre eux sont hors de notre contrôle. :) Donc, si je peux voir le contexte complet, je peux vous donner une suggestion pour aider le navigateur.

L'application est en fait écrite en CoffeeScript qui est compilé en JavaScript à l'aide de require.js. Le point d'entrée principal ressemble à ceci :

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

J'ai également essayé sans le wrapper context et cela ne semble rien changer. Il a toujours enregistré les appels throw qui ont été effectués plus haut dans la pile d'appels tout en ignorant ceux en bas.

Courez-vous Raven.install()

Et pour require.js, si vous vouliez explicitement encapsuler des modules, vous feriez :

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

Je l'ai oublié dans l'extrait, mais j'appelle install() après config()

Je n'ai pas essayé d'enrouler les modules, mais je me suis dit que si cela fonctionnait déjà à certains endroits, pourquoi pas à d'autres ?

Tout dépend vraiment de la pile d'appels. Lorsque les choses commencent à entrer dans un pays asynchrone, cela devient difficile. Par exemple, cela ne ferait pas comme prévu :

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

La fonction interne est exécutée dans son propre contexte en dehors du contexte principal. Node.js résout ce problème avec une chose appelée "domaines", mais malheureusement, ceux-ci n'existent pas dans les navigateurs.

Donc, si une erreur n'est pas détectée et remonte jusqu'au sommet, elle est généralement rejetée car elle est 100% sans valeur à ce stade.

Ah, je vois. Peut-être existe-t-il un moyen d'utiliser window.onerror ?

FWIW, si possible, le moyen le plus sûr de capturer une exception consiste à utiliser explicitement Raven.captureException . Je comprends que ce n'est pas toujours faisable, mais juste un FYI.

Ainsi, un bloc try...except explicite est le plus fiable :

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

Droit. Bien sûr, ce serait formidable de capturer automatiquement les erreurs, mais JavaScript n'en fait pas un jeu facile à jouer...

@pheuter Non. :) Et c'est la partie amusante. Une fois qu'une erreur arrive à window.onerror, ce n'est plus un objet Error réel. Il s'aplatit à juste une chaîne inutile. Et cela impose également des problèmes de sécurité inter-domaines. Donc, fondamentalement, une fois qu'une erreur atteint window.onerror , elle est généralement ignorée car la seule information dont nous disposons peut être uniquement : "Script error." .

Suce. Oh bien, j'apprécie la précision!

Non, Javascript ne le fait pas. C'est vraiment terrible, en fait. :) Je recherche et explore activement les moyens d'exploiter le navigateur pour nous donner de meilleures informations. L'idée m'a même traversé l'esprit de monkey patch Function.prototype.call . Mais c'est probablement une très mauvaise nouvelle.

Totalement! Si vous avez des recommandations ou des suggestions pour clarifier la documentation, n'hésitez pas à m'en faire part. Je suis toujours à la recherche de ce truc.

Will do, les docs de configuration et d'utilisation ont été assez simples et faciles à suivre.

Je me demande s'il existe un moyen d'étendre Error pour que cela fonctionne.

@mattrobenolt , c'est l'approche que nous adoptons avec CoffeeScript.

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

Ensuite, utilisez simplement throw new Error "Test Error"

Commentaire mis à jour ci-dessus pour clarification.

Hmm. Je jouerai avec ça pendant le week-end. La dernière fois que j'ai essayé, cela ne me laissait pas patcher sur window.Error. Je vais réessayer dans d'autres navigateurs et voir ce qui est possible.

Merci pour l'information!

Aussi, pouvez-vous me donner cela en Javascript normal ? Je suis à peu près sûr de ce qu'il fait, je veux juste vérifier. Je n'écris pas Coffeescript.

Voici:

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);

Maintenant que j'y pense, c'est une approche erronée. Le simple fait de remplacer le constructeur va amener Raven à capturer chaque objet d'erreur, qu'il soit lancé ou non. :)

Pour votre information, errorception a trouvé un moyen de gérer cela. Ce serait cool si raven-js pouvait faire la même chose.

@dmcquay Pouvez-vous fournir un exemple capturé par Errorception ? Je peux probablement faire de l'ingénierie inverse.

Je suppose en fait que tous les gestionnaires d'erreurs JS sont à 50% raven.js ;)

:caca:

@BYK , des idées ?

Je n'ai aucune connaissance de l'intérieur sur la perception d'erreurs. J'utilise le service et il semble fonctionner comme annoncé. C'est tout ce que je sais.

J'ai inspecté leur fonctionnement et il semble qu'ils s'attachent simplement à window.onerror et ne se soucient pas de la trace de la pile. Du moins pour ce genre de choses.

Le détournement de l'objet Error fonctionne pour Firefox, mais le point de @mattrobenolt sur la capture de tous, même ceux qui ne sont pas lancés, est une préoccupation valable.

Une solution de contournement sale pour cela pourrait être de stocker les instances Error créées en détournant le constructeur global et également d'écouter onerror et de comparer les message , fileName et lineNo arguments avec les propriétés des objets Error stockés. Si une correspondance est trouvée, supprimez-la de la file d'attente et signalez-la.

Lors de l'évaluation de tous les services de notification d'erreur, j'ai remarqué que certains services spécifiques à Javascript (tels que https://qbaka.com/) suivent la trace de la pile et affichent l'action de l'utilisateur qui a conduit à une erreur particulière. Dommage que la perception d'erreur ne le fasse pas car elle semble supérieure à tous les autres égards.

Nous utiliserons Sentry pour notre code Django, et je suis tombé sur ce problème en cherchant des informations sur le fonctionnement de Sentry pour Javascript. L'implémentation actuelle de raven-js nécessite-t-elle que le code intercepte explicitement toutes les erreurs JS et les signale à Sentry ?

@ adityar7 Ce n'est pas le cas. Raven.js essaie de son mieux de patcher les singes et d'intercepter les choses s'il le peut. Dans certains cas plus extrêmes, vous devrez peut-être envelopper explicitement, mais nous nous efforçons de faire en sorte que les choses se produisent automatiquement.

@mattrobenolt Je l'ai fait fonctionner en corrigeant une syntaxe. Merci!

Cette page vous a été utile?
0 / 5 - 0 notes