web-dev-qa-db-fra.com

Comment puis-je relancer une exception en Javascript, tout en préservant la pile?

En Javascript, supposons que je veuille effectuer un nettoyage lorsqu'une exception se produit, mais laissez l'exception continuer à se propager dans la pile, par exemple:

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 le renvoi de l'exception entraînent la perte des informations de trace de pile jusqu'à ce point, de sorte que si l'exception est de nouveau interceptée, plus haut dans la pile, la trace de pile ne descend que vers le bas. -jeter. Cela craint parce que cela signifie qu'il ne contient pas la fonction qui a réellement lancé l'exception.

En fin de compte, try..finally a le même comportement, au moins Chrome (c’est-à-dire que le problème n’est pas précisément la relance, mais la présence de toute exception bloc de gestionnaire du tout.)

Est-ce que quelqu'un connaît un moyen de relancer une exception en Javascript mais de conserver la trace de pile qui lui est associée? En cas d'échec, que diriez-vous de suggestions pour ajouter d'autres gestionnaires de nettoyage sécurisés aux exceptions, tout en capturant des traces de pile complètes lorsqu'une exception se produit?

Merci pour tous les pointeurs :)

134
Geoff

Ceci est un bug dans Chrome. Renvoyer une exception doit conserver la trace des appels.

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

Je ne connais aucune solution de contournement.

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

73
Glenn Maynard

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

 génère une nouvelle erreur ("message"); 

et si vous utilisez le code tel que vous l'avez écrit, la propriété de pile sera pas modifiée lorsque vous afficherez à nouveau l'erreur.

22
Mike Stay