Как я могу выбросить исключение в Javascript, но сохранить стек? - PullRequest
132 голосов
/ 17 сентября 2010

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

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

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

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

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

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

Ответы [ 2 ]

71 голосов
/ 14 декабря 2010

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

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

Я не знаю никакого обходного пути.

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

22 голосов
/ 17 сентября 2010

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

   throw new Error("message");

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

...