如何在Javascript中重新抛出异常,但保留堆栈?

在Javascript中,假设我想在发生异常时执行一些清理,但让异常继续向上传播堆栈,例如:

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

此代码的问题在于,捕获并重新引发异常会导致到该点的堆栈跟踪信息丢失,因此,如果随后再次捕获异常,则在堆栈的较高位置,堆栈跟踪只会向下传递。这很糟糕,因为这意味着它不包含实际引发异常的函数。

事实证明,尝试..最后具有相同的行为,至少在Chrome中(也就是说,问题恰恰不是重抛,而是存在任何异常处理程序块。

有没有人知道一种方法可以在Javascript中重新抛出异常,但保留与之相关的堆栈跟踪?如果做不到这一点,那么如何建议其他方法来添加异常安全清理处理程序,同时在发生异常时捕获完整的堆栈跟踪?

感谢您的任何指点:)


答案 1

这是Chrome中的一个错误。重新引发异常应保留调用跟踪。

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

我不知道任何解决方法。

我最终没有看到问题。我确实看到异常在某些情况下没有在最终之后显示在错误控制台上,但是那个异常似乎在开发版本中得到了修复。


答案 2

Error 对象的 stack 属性与 Error 对象本身同时创建,而不是在引发该对象时创建。由于成语,它们通常是相同的

   throw new Error("message");

如果按照编写代码的方式使用代码,则在重新抛出错误时不会更改 stack 属性。