2010-09-17 86 views
100

在Javascript中,假设我要当发生异常进行一些清理工作,但让异常继续传播了栈,如:如何重新抛出JavaScript中的异常,但保留堆栈?

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

这段代码的问题是,捕捉和重新抛出异常的原因直到该点的堆栈跟踪信息丢失,以便如果随后再次捕获异常,在堆栈上更高,则堆栈跟踪仅下降到重新抛出。这很糟糕,因为这意味着它不包含实际抛出异常的函数。

事实证明,try..finally具有相同的行为,至少在Chrome中(也就是说,它不是重新抛出问题,而是存在任何异常处理程序块。 )

有谁知道的方式重新抛出在Javascript中的异常,但保留与此相关的堆栈跟踪?如果不这样做,那么如何增加异常安全的清理处理程序的其他方法的建议,以及在发生异常时捕获完整的堆栈跟踪?

感谢您的指点:)

+7

0x3a28213a - 期待着我感谢;-) – bacar 2012-08-17 18:03:57

+0

杜佩:https://stackoverflow.com/questions/5249960/javascript-rethrowing-an-exception-preserving-the-stack-trace – MatthewMartin 2015-11-02 19:17:51

+0

这个问题应该是因为关闭它指的是2012年修复的Chrome bug。 – 2017-02-09 08:06:36

回答

53

这是浏览器的错误。重新发起异常应该保留呼叫追踪。

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

我不知道任何解决办法的。

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

+13

这个错误似乎已经被修复了。 – mzedeler 2013-05-15 10:31:00

15

Error对象的堆栈属性是在同一时间为Error对象本身产生的,而不是在点它抛出。它们往往是相同的,因为成语

 
    throw new Error("message"); 

的,如果你使用就像你写它的代码,堆栈属性将来,当你重新抛出的错误改变。

+1

这不是真的(可能取决于平台)。我现在使用的js引擎(Rhino)重置了throw语句中的堆栈,丢失了原始堆栈。 – 2017-10-06 19:26:54

+0

也许是这样,但rhino-1.7.7.2.jar不会改变它。你使用什么版本? – 2017-10-07 05:11:20

相关问题