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

How can I rethrow an exception in Javascript, but preserve the stack?

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

1
2
3
4
5
6
7
8
9
try {
  enterAwesomeMode();
  doRiskyStuff(); // might throw an exception
} catch (e) {
  leaveAwesomeMode();
  throw e;
}
doMoreStuff();
leaveAwesomeMode();

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

事实证明,Try..Finally具有相同的行为,至少在chrome中是这样的(也就是说,问题不在于重新抛出,而在于是否存在任何异常处理程序块)。

有人知道在javascript中重新引发异常但保留与之相关联的堆栈跟踪的方法吗?如果失败了,对于添加异常安全清理处理程序的其他方法的建议如何,同时在发生异常时捕获完整的堆栈跟踪?

感谢您的指点:)


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

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

我不知道有什么解决办法。

我看不出最后的问题。在某些情况下,在最后一次之后,我确实会看到异常不会出现在错误控制台上,但在开发构建中似乎已经修复了异常。


错误对象的堆栈属性与错误对象本身同时创建,而不是在它被抛出的点创建。由于习惯用法,它们通常是相同的。

1
   throw new Error("message");

如果您像编写代码一样使用代码,那么当您重新引发错误时,Stack属性将不会被更改。