Wie kann ich eine Ausnahme in Javascript erneut auslösen, aber den Stapel beibehalten?


150

Angenommen, ich möchte in Javascript eine Bereinigung durchführen, wenn eine Ausnahme auftritt, aber die Ausnahme den Stapel weiter verbreiten, z.

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

Das Problem mit diesem Code besteht darin, dass das Abfangen und erneute Auslösen der Ausnahme dazu führt, dass die Stack-Trace-Informationen bis zu diesem Punkt verloren gehen. Wenn die Ausnahme anschließend weiter oben im Stack erneut abgefangen wird, geht der Stack-Trace nur bis zum erneuten Wert zurück -werfen. Das ist scheiße, weil es bedeutet, dass es nicht die Funktion enthält, die die Ausnahme tatsächlich ausgelöst hat.

Wie sich herausstellt, hat try..finally das gleiche Verhalten, zumindest in Chrome (das heißt, es ist nicht genau das erneute Werfen, das genau das Problem ist, sondern das Vorhandensein eines Ausnahmebehandlungsblocks überhaupt.)

Kennt jemand eine Möglichkeit, eine Ausnahme in Javascript erneut auszulösen, aber die damit verbundene Stapelverfolgung beizubehalten? Wenn dies nicht der Fall ist, wie wäre es mit Vorschlägen für andere Möglichkeiten, um ausnahmesichere Bereinigungshandler hinzuzufügen und gleichzeitig vollständige Stapelspuren zu erfassen, wenn eine Ausnahme auftritt?

Danke für alle Hinweise :)


Antworten:


78

Dies ist ein Fehler in Chrome. Durch erneutes Auslösen einer Ausnahme sollte die Anrufverfolgung erhalten bleiben.

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

Ich kenne keine Problemumgehung.

Ich sehe das Problem endlich nicht. Ich sehe Ausnahmen, die in einigen Fällen lautlos nicht auf der Fehlerkonsole angezeigt werden, aber diese scheinen in Entwicklungs-Builds behoben zu sein.


4
Dieses Problem wurde inzwischen geschlossen.
Zachary Burns

23

Die Stack-Eigenschaft eines Fehlerobjekts wird gleichzeitig mit dem Fehlerobjekt selbst erstellt und nicht an dem Punkt, an dem es ausgelöst wird. Sie sind oft gleich wegen der Redewendung

   neuen Fehler werfen ("Nachricht");

Wenn Sie den Code so verwenden, wie Sie ihn geschrieben haben, wird die Stack-Eigenschaft nicht geändert, wenn Sie den Fehler erneut auslösen.


5
Dies ist nicht wahr (möglicherweise plattformabhängig). Die js-Engine, die ich jetzt verwende (Rhino), setzt den Stapel in der throw-Anweisung zurück und verliert den ursprünglichen Stapel.
Ted Bigham

1
Vielleicht ja, aber rhino-1.7.7.2.jar ändert es nicht. Welche Version verwenden Sie?
Mike Stay
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.