2010-09-17 84 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

相關問題