2009-03-05 60 views
9

我最近不得不爲一位同事開發的現有服務開發一個額外的模塊。他放在try/catch塊中的主要工作職能用來捕獲冒泡到這個級別的所有unhadled例外,帶有堆棧跟蹤信息等一起記錄他們:如何實現頂級異常處理?

try 
{ 
    // do main work 
} 
catch(Exception ex) 
{ 
    // log exception info 
} 

儘管這使得程序非常穩定(如在'不太可能崩潰'),我討厭它,因爲當我測試我的代碼時,我沒有看到由它造成的異常。當然,我可以查看異常日誌並查看是否有新條目,但是我非常希望在拋出異常時獲得直接反饋(請將代碼中的光標放在代碼的右側)。

至少在我還在編碼和測試的時候,我刪除了這個頂級的try/catch。但是現在我的任務已經完成了,我必須決定是否將它放回發佈版本,否則。 我認爲我應該這樣做,因爲它使服務更穩定,而且它的全部要點是它在後臺運行而不需要任何監督。另一方面,我已經讀過,應該只是調用特定的例外(如IoException),而不是一般的Exception

你對這個問題的建議是什麼?

順便說一下,該項目是用C#編寫的,但我也對非.NET語言的答案感興趣。

+0

另請參見 http://stackoverflow.com/questions/576532/is-dying-is-awesome-preferred – Brian 2009-03-05 21:51:38

回答

10

放回去。

這個異常應該只在測試時纔有意義。否則,將它彈出給用戶是沒有意義的。

伐木很好。

您還可以使用Visual Studio定義的DEBUG符號作爲調試版本的標誌。

... 
    } catch(Exception e) { 
#if DEBUG 
      throw; 
#else 
      log as usual 
#endif 
    } 

因此,下一次需要修改調試標誌應設置爲true,並會出現異常。

+0

嗯,我喜歡調試標誌! – Treb 2009-03-05 22:02:25

+0

他不應該用'扔'而不是'扔e'?否則,堆棧跟蹤將被清除(或者不太確定)。 – strager 2009-03-05 22:10:14

+0

@strager:是!上面的例子將掩蓋原始異常。只需使用'扔'。 – 2009-03-05 22:21:03

2

理想情況下,您希望儘可能接近它發生的位置處理異常,但這並不意味着全局異常處理程序是一個壞主意。特別是對於必須不惜一切代價繼續運行的服務。我會繼續你一直在做的事情。在調試時禁用它,但將其留在原位進行生產。

請記住它應該用作安全網。儘管如此,他們仍然試圖捕捉所有的異常情況,然後才能提升這一點

4

在任何Java應用程序,你幾乎總是要定義未捕獲的異常的異常處理程序像這樣的東西:

Thread.setDefaultUncaughtExceptionHandler(...); 

其中,將捕獲這些未捕獲的異常對象將至少登錄失敗等等你有機會了解它。否則,不能保證你會被通知一個線程取得了一個例外 - 除非它是你的主線程。

除了這樣做以外,我的大部分線程都有一個try/catch,我會在其中捕獲RunnableException(但不是Error)並記錄下來......有些線程會在這種情況發生時死亡,其他線程會記錄並忽略,其他人將向用戶顯示投訴,並根據應用程序的需要由用戶決定。這個try/catch是線程的根本,Runnable.run()方法或同等方法。由於try/catch位於Thread的根部,因此不需要禁用此捕獲。

當我在C#中編寫代碼時,我的代碼類似。但這一切都取決於應用程序的需要。異常是否會破壞數據?那麼,不要忽視它。總是記錄它,但然後讓應用程序死亡。然而,大多數例外都不是這種類型。

2

追求所有例外並使程序「穩定」的願望非常強烈,這個想法對每個人來說都是非常誘人的。你指出的問題是,這只是一個詭計,並且該程序可能非常糟糕,並且更糟糕,沒有失敗的跡象。沒有人經常監視日誌。
我的建議是嘗試說服其他開發人員進行廣泛的測試,然後將其部署到生產環境而不是外部捕獲。

1

如果您想在異常發生時看到異常,可以在Visual Studio中進入DEBUG菜單,選擇EXCEPTIONS,並在拋出異常時立即告訴調試器中斷。你甚至可以選擇什麼類型的例外。 :)