82 votes

Traitement des exceptions en JavaScript

Quelle est la meilleure technique pour attraper TOUTES les exceptions lancées en JavaScript ?

Évidemment, la meilleure technique est d'utiliser try...catch. Mais avec les callbacks ansynchrones et ainsi de suite, cela peut devenir délicat.

Je sais que les navigateurs IE et Gecko prennent en charge window.onerror, mais qu'en est-il d'Opera et de Safari ?

Voici une série de cas de test pour lesquels j'aimerais avoir une solution centrale de gestion des exceptions :

// ErrorHandler-Test1
var test = null;
test.arg = 5;
// ErrorHandler-Test2
throw (new Error("Hello"));
// ErrorHandler-Test3
throw "Hello again";
// ErrorHandler-Test4
throw {
    myMessage: "stuff",
    customProperty: 5,
    anArray: [1, 2, 3]
};
// ErrorHandler-Test5
try {
    var test2 = null;
    test2.arg = 5;
} catch(e) {
    ErrorHandler.handleError(e);
}
// ErrorHandler-Test6
try {
    throw (new Error("Goodbye"));
} catch(e) {
    ErrorHandler.handleError(e);
}
// ErrorHandler-Test7
try {
    throw "Goodbye again";
} catch(e) {
    ErrorHandler.handleError(e);
}
// ErrorHandler-Test8
try {
    throw {
        myMessage: "stuff",
        customProperty: 5,
        anArray: [1, 2, 3]
    };
} catch(e) {
    ErrorHandler.handleError(e);
}

Si vous pensez à d'autres cas de test, veuillez les mentionner. Plusieurs de ces cas mentionnent une méthode ErrorHandler.handleError. Il s'agit simplement d'une directive suggérée lors de l'utilisation de try...catch.

0 votes

Juste parce qu'il est clair que vous n'avez pas remarqué les commentaires sur ma réponse : il semble que vous m'ayez rétrogradé pour "énoncé dans la question" alors que c'est lu comme une question : "mais qu'en est-il d'Opera et Safari ?" J'ai répondu spécifiquement à une question posée ici. WTF ?

1 votes

Dans WebKit, window.onerror manquant est un problème depuis 2003 mais on dirait que c'est enfin résolu . Bien sûr, Opera restera obstiné.

0 votes

Pour info, window.onerror fonctionne bien dans - Firefox 7.0.1 - IE 8 - Chrome 16 - Opera 11.60

23voto

Karl Points 1085

Si vous utilisez une bibliothèque comme jQuery pour assigner tous vos gestionnaires d'événements, vous pouvez utiliser une combinaison des éléments suivants window.onerror et en enveloppant le code du gestionnaire d'événements jQuery et la fonction on ready avec une fonction de gestion des erreurs (voir : Suivi des erreurs JavaScript : Pourquoi window.onerror n'est pas suffisant ).

  • window.onerror : attrape toutes les erreurs dans IE (et la plupart des erreurs dans Firefox), mais ne fait rien dans Safari et Opera.
  • Gestionnaires d'événements jQuery : permet de détecter les erreurs liées aux événements jQuery dans tous les navigateurs.
  • Fonction jQuery ready : permet de détecter les erreurs d'initialisation dans tous les navigateurs.

0 votes

J'avais déjà lu l'article qui ne propose aucune solution. Je n'utilise pas jQuery, mais ce que vous sous-entendez m'inquiète. Voulez-vous dire que jQuery mange les exceptions ! Ou est-ce qu'il fournit simplement une fonctionnalité de journalisation (qui n'est utile qu'après avoir répondu à ma question initiale) ?

0 votes

JQuery ne fait rien de spécial avec les exceptions. Mais si vous utilisez jQuery pour ajouter tous vos événements, il vous donne un seul endroit pour ajouter votre déclaration try catch et votre code de gestion des erreurs, comme expliqué dans le deuxième lien de ma réponse.

2 votes

Le lien fourni a été déplacé : blogs.cozi.com/tech/2008/04/

21voto

eyelidlessness Points 28034

WebKit (Safari, Chrome, etc.) semble désormais prendre en charge les éléments suivants onerror .

Poste original : Pour autant que je sache, WebKit/Safari ne prend pas en charge la fonction onerror événement. Ce qui est une honte.

19 votes

Euh, non ça ne l'est pas. Demandé dans la question : "mais qu'en est-il d'Opera et Safari ?"

0 votes

Comme dans, j'ai répondu spécifiquement à une question posée dans le post de la question.

8 votes

Je pense qu'il voulait dire "que [faire] pour Opera et Safari [qui n'ont pas window.onerror]" ?

7voto

adamfisk Points 409

En fait, l'approche de Jquery n'est pas si mauvaise. Voir :

http://docs.jquery.com/Events/error#fn

et :

$(window).error(function(msg, url, line){
  $.post("js_error_log.php", { msg: msg, url: url, line: line });
});

11 votes

Pour ceux qui découvrent ceci maintenant - jquery recommande en fait de ne pas lier un événement à l'événement window.error - voir le lien de documentation ci-dessus. Extrait : Un gestionnaire d'événement d'erreur jQuery ne doit pas être attaché à l'objet window. [...] Utilisez plutôt window.onerror.

0 votes

Bien sûr, ce n'est pas censé être lié de cette façon, c'est illogique ! beaucoup d'erreurs pourraient se produire au moment où cette liaison a été faite (si elle a même été faite avec succès ...)

6voto

MKatleast3 Points 51

Attrapez toutes les exceptions avec votre propre gestionnaire d'exceptions et utilisez instanceof.

$("inuput").live({
    click : function (event) {
        try {
            if (somethingGoesWrong) {
                throw new MyException();
            }
        } catch (Exception) {
            new MyExceptionHandler(Exception);
        }

    }
});

function MyExceptionHandler(Exception) {
    if (Exception instanceof TypeError || 
        Exception instanceof ReferenceError || 
        Exception instanceof RangeError ||  
        Exception instanceof SyntaxError ||     
        Exception instanceof URIError ) {
        throw Exception; // native error
     } else {
         // handle exception
     }
}

MyExcetpionHandler lancera une erreur native car il n'y a pas de bloc try-catch.

Visitez http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

4voto

wolfgang Points 41

try-catch n'est pas toujours la meilleure solution. Par exemple, dans Chrome 7.0, vous perdez la trace de la pile dans la fenêtre de la console. Relancer l'exception ne sert à rien. Je ne connais pas de solution qui préserve les traces de la pile. y vous laissant réagir à l'exception.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X