2010-09-17 19 views
100

En Javascript, supposons que je veux effectuer un nettoyage lorsqu'une exception se produit, mais laisse l'exception continuer à propager la pile, par exemple:Comment puis-je renvoyer une exception dans Javascript, mais conserver la pile?

try { 
    enterAwesomeMode(); 
    doRiskyStuff(); // might throw an exception 
} catch (e) { 
    leaveAwesomeMode(); 
    throw e; 
} 
doMoreStuff(); 
leaveAwesomeMode(); 

Le problème avec ce code est que la capture et rethrowing les causes d'exception les informations de trace de la pile jusqu'à ce point sont perdues, de sorte que si l'exception est reprise plus tard, plus haut sur la pile, la trace de la pile ne descend que jusqu'à la relance. Cela craint parce que cela signifie qu'il ne contient pas la fonction qui a réellement jeté l'exception. Comme il s'avère, try..finally a le même comportement, dans au moins Chrome (c'est-à-dire que ce n'est pas le re-throw qui est précisément le problème, mais la présence d'un bloc de gestionnaire d'exception).

Est-ce que quelqu'un connaît un moyen de réécrire une exception dans Javascript, mais conserve la trace de la pile qui lui est associée? A défaut, que diriez-vous des suggestions pour d'autres façons d'ajouter des gestionnaires de nettoyage sans exception, tout en capturant des traces de pile complètes lorsqu'une exception se produit?

Merci pour tous les pointeurs :)

+7

0x3a28213a - avec impatience mes remerciements – bacar

+0

Dupe: https://stackoverflow.com/questions/5249960/javascript-rethrowing-an-exception-preserving-the-stack-trace – MatthewMartin

+0

Cette question devrait être fermée parce que il fait référence à un bug de Chrome corrigé en 2012. –

Répondre

53

Ceci est un bug dans Chrome. La réimpression d'une exception doit conserver la trace d'appel.

http://code.google.com/p/chromium/issues/detail?id=60240

Je ne sais pas d'une solution de contournement.

Je ne vois pas le problème avec enfin. Je vois des exceptions ne pas apparaître silencieusement sur la console d'erreur dans certains cas après un final, mais celui-ci semble être corrigé dans les versions de développement.

+13

Ce bug semble avoir été corrigé maintenant. – mzedeler

15

La propriété de la pile d'un objet d'erreur est créé en même temps que l'objet d'erreur lui-même, pas au point où il est jeté. Ils sont souvent les mêmes à cause de l'idiome

 
    throw new Error("message"); 

et si vous utilisez le code comme vous l'avez écrit, la propriété de la pile ne pas être modifiés lorsque vous réémettre l'erreur.

+1

Ceci n'est pas vrai (peut-être dépendant de la plateforme). Le moteur js que j'utilise maintenant (Rhino) réinitialise la pile sur l'instruction throw, perdant la pile d'origine. –

+0

Peut-être, mais rhino-1.7.7.2.jar ne le change pas. Quelle version utilisez-vous? –