2011-09-28 84 views
10

我會先用我的用例迅速激發這個問題。 我的庫需要將Java異常分類器公開給它插入的框架。例如:鏈式異常的循環

enum Classification { FATAL, TRANSIENT, UNKNOWN } 

Classification classify(Throwable t) { 
    if (t instanceof MyTransientException) 
     return Classification.TRANSIENT; 
    else if (t instanceof MyFatalException) 
     return Classification.FATAL; 
    else 
     return Classification.UNKNOWN; 
} 

有時候,和原因在我的掌握,傳遞的例外是圍繞着一個我很感興趣,所以我想搜索的連鎖事業爲它的包裝。我最初的想法是:

Classification classify(Throwable t) { 
    if (t == null) 
     return Classification.UNKNOWN; 

    if (t instanceof MyTransientException) 
     return Classification.TRANSIENT; 
    else if (t instanceof MyFatalException) 
     return Classification.FATAL; 
    else 
     return classify(t.getCause()); 
} 

不幸的是,這可能會導致無窮遞歸如果傳遞的例外在其因果鏈的循環。這樣的例外很可能不會被傳遞,並且如果創建了這樣一個例外,那麼可以認爲這是系統中其他地方的錯誤,但是我對我的庫負責生產的可能性感到非常不舒服發生中斷。 Throwable的API和javadoc並沒有明確禁止這種可能性,除了循環在因果鏈中本身無意義的想法。

我注意到,番石榴有一個@Beta方法來提取因果鏈,Throwables.getCausalChain,但它的實現容易出現同樣的問題 - 它會結束投擲OOME。

我打算使用identity hash set來檢測週期並降低風險,但我想聽聽其他人如何看待此問題。你認爲我過於防守嗎?你會怎麼做?

回答

13

非常好,你是如此的認真。但你不想進入製造凱夫拉靴子的業務。

如果用戶做了一些事情,即使Throwable.printStackTrace進入無限遞歸,該用戶超出了幫助。不要擔心這一點。