Как я могу перестроить исключение в Javascript, но сохранить стек?


в Javascript предположим, что я хочу выполнить некоторую очистку, когда происходит исключение, но пусть исключение продолжает распространяться вверх по стеку, например:

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

проблема с этим кодом заключается в том, что перехват и перепрофилирование исключения приводит к потере информации трассировки стека до этого момента, так что если исключение впоследствии будет перехвачено снова, выше по стеку, трассировка стека только переходит к повторному броску. Это отстой, потому что это означает, что он не содержит функция, которая фактически вызвала исключение.

Как оказалось, попробовать..наконец, имеет такое же поведение, по крайней мере, в Chrome (то есть это не повторный бросок, который является проблемой точно, но наличие любого блока обработчика исключений вообще.)

кто-нибудь знает способ перестроить исключение в Javascript, но сохранить трассировку стека, связанную с ним? В противном случае, как насчет предложений по другим способам добавления обработчиков очистки, безопасных для исключений, а также захвата полные трассировки стека, когда происходит исключение?

Спасибо за любые советы :)

2 116

2 ответа:

Это ошибка в Chrome. Повторное создание исключения должно сохранить трассировку вызова.

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

Я не знаю ни одного решения.

Я не вижу проблемы с finally. Я вижу, что исключения молча не отображаются на консоли ошибок в некоторых случаях после завершения, но это, похоже, исправлено в сборках разработки.

свойство stack объекта Error создается одновременно с самим объектом Error, а не в точке его выброса. Они часто одинаковы из-за идиомы

   throw new Error("message");

и если вы используете код так же, как вы его написали, свойство stack будет не быть изменены, когда вы перестроить ошибку.