2013-10-08 155 views
1

當然,異常應該在您認爲合適的適當級別進行處理。假設您不知道如何處理checked異常,並將其包裝在適當的自定義未經檢查的異常中,以傳播到最高級別(假定您不處理該包裝的異常以及某些介質中的其他可能的未經檢查的異常將原始異常發生的級別(因爲你不想或不知道如何)級別分開)。更進一步,所有未處理的異常(未經檢查和檢查,未經檢查包裝)達到頂層(主要方法,webapp控制器等);當然我應該做點什麼。我想要做的就是通過使用日誌條目通知開發人員某些錯誤,並告知用戶他的請求無法正確服務(根據適用於該例外的消息使用不同的消息)。要做到這一點,我使用捕獲塊RuntimeException(如果它捕獲的不是自定義的未經檢查的異常,我會向用戶發送「發生嚴重問題」或類似的消息;這種非自定義未經檢查的異常的概率將被緩存爲大於零,並且你必須進行溝通)。一些文章(first,second)建議不要通過catch塊中的超類型捕獲子類的實例(或者它只與檢查的異常有關?)。如果我在catch塊中使用了準確的異常類型,我會錯過一些未經檢查的異常,並且應用程序會崩潰(當然,在那些執行日誌記錄和通知用戶的catch塊中會有重複的代碼片斷)。舉個例子,我可以提供在JSP轉換階段建造和使用超類型趕上那超的子類的實例片斷頂層的異常處理

// some code 
try { 
    // body of translated JSP here... 
} catch (Exception e) { 
    out.clear(); 
    pageContext.handlePageException(e); 
} 
// some code 

我的問題:是這個概念是正確的catch塊使用RuntimeException在頂層向開發者彙報所有問題並向用戶通報所有發生的問題?當然,在這種情況下,異常處理只是通知開發人員和用戶發生問題,並且沒有恢復策略。也許很難將這個概念稱爲異常處理。請糾正我,我欣賞關於這個概念的任何想法。

回答

0

結束語所有Exception s的一個RuntimeException,並在main方法處理它們,或其它地方你定義爲你的最高水平,是一個非常糟糕的做法。 Exception的實例應該儘可能接近它們被拋出的位置,因爲它們存在以識別可以從中恢復的錯誤。例如,如果您嘗試打開文件並獲取FileNotFoundException,則應對此採取措施(顯示錯誤消息,在錯誤日誌中添加條目等)。

大部分時間,RuntimeException代表編程錯誤()。通常情況下,他們表示應用程序處於不穩定狀態,如果不是不可能的話,恢復也很困難。IllegalStateException,NullPointerExceptionIndexOutOfBoundsException就是這種情況的例子。

現在,您提出的概念,其中所有RuntimeException都被頂級方法所捕獲,對於包含超過幾百行代碼的任何軟件來說都不是一個可行的解決方案,在較短的程序中是一種非常糟糕的做法。

假設您有一個具有10萬行代碼的應用程序。一旦拋出異常,您的頂級方法將無法正確處理異常。如果它是NullPointerException,它應該怎麼做?它從哪裏拋出?那麼CloneNotSupportedException?您將擁有長達數十頁的頂級方法,可處理所有可能的例外情況,並擁有史上最大的if-then-else聲明。另外,如果你實現了這樣一個概念,你應該知道,無論何時拋出異常,你的應用程序都會在你的頂級方法中的catch塊中。一旦記錄了錯誤,您將永遠無法將控制權返回給您的應用程序的那部分產生錯誤的部分,因爲您將不會擁有引發Exception的上下文。

+0

感謝您的回答。你建議不要推遲處理檢查到的頂級異常(儘快完成(發送消息,創建日誌條目等)),我同意。但是我應該如何處理髮生意外的未經檢查的異常(NullPointerException等)?我同意這些未經檢查的異常,因爲我的編碼和恢復是不可能的;但是如果我沒有在頂層捕獲這些異常,應用程序將崩潰,這種情況比我發現這些異常並提供消息時更糟糕 – stovfl

+0

You可以實現您自己的[UncaughtExceptionHandler](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.UncaughtExceptionHandler.html),並使其記錄異常跟蹤,顯示錯誤消息給用戶,然後關閉應用程序。 – Laf

+0

感謝您的回答和努力 – stovfl

0

我認爲在你的情況下這是正確的路要走。

你不希望用戶最好通過看到一個堆棧跟蹤,並在最壞的情況可能暴露的安全問題,通過看到後端服務器名,數據庫憑據,數據庫模式等相混淆

你抓應該隱藏這些來自用戶的信息並向用戶輸出有用的錯誤信息,所以至少他們知道問題是什麼。

我與你的代碼唯一擔心的是也許你應該分開趕上RuntimeExceptionException(甚至Throwable

try { 
    // body of translated JSP here... 
}catch(RuntimeException re){ 
    //something unexpected 
    //handle here 
} catch (Exception e) { 
    //checked exception 
    //handle here 
} 
+0

非常感謝您的回答。閱讀許多文章,聲稱「你不應該通過catch塊中的超類型捕獲子類的實例」使我困惑。 – stovfl

+0

通常情況下你不應該這樣做,但是在main()或最高級別中,有時避免向用戶顯示很多信息是適當的。 – dkatzel