2011-10-28 76 views
1

我在這裏提出了幾個問題,並閱讀了一些關於異常處理的文章,但不要以爲我真的在抓,什麼時候不應該處理異常。從我讀過的文章中可以看出「只處理可以從中恢復的異常」這是什麼意思。如果我不能處理異常,我該怎麼辦?讓它傳播回堆棧?如果我不處理它,我該如何記錄它並顯示用戶友好的錯誤消息。大多數人在網絡應用和網絡服務中做什麼?處理.net中的異常

舉個例子說,我有一個從SQL

try{ 
    //do something with db 
}catch(SqlException ex){ 
//what should i do here 
//should i call code again to retry getting data from db 
}catch(Exception ex){ 
//should i even catch exception of type exception 
} 

如何在較低層處理異常提取數據的較低層數據層?我應該讓這個例外冒出來嗎?如果是這樣的話,如果我想要捕獲sqlexception類型的異常,那麼我需要對庫的引用sqlexception是其中的一部分,但我肯定不應該在與數據訪問無關的層中引用該庫。

+0

這些其他主題可能會幫助:http://stackoverflow.com/questions/2765086/exception-handling-policy-in-libraries –

+0

http://stackoverflow.com/questions/5772237/exception-handling- in-layered-architecture –

回答

1

異常管理是一個很大的主題,所以我只會在這裏觸及表面。

從文章香港專業教育學院讀它規定爲「只處理你可以恢復的異常」是什麼意思是說。

如果你不知道如何從一個特定的異常中恢復,那麼就不是通常捕獲它的任何一點。如果它是一個Web應用程序或服務,Web服務器本身將處理日誌記錄和恢復。

在某些情況下,您需要捕獲異常,以便可以進行通用恢復,例如通過取消或反轉事務。在這種情況下,可接受的方法是
捕獲異常,執行通用恢復,然後再次拋出異常。

如果我無法處理異常,我該怎麼做。讓它支持堆棧?

是的。

如果我不處理它,我怎麼可以登錄並提供用戶友好的錯誤消息。大多數人在網絡應用和網絡服務中做什麼?

Web服務器將記錄異常。如果您想在Web應用程序中顯示用戶友好的錯誤消息,則可以捕獲/登錄堆棧的最高級別並重新指向錯誤消息。再次,我會嘗試不捕獲System.Exception - 而是列出應用程序拋出的異常,並在呈現針對每種類型定製的消息之前捕獲這些類型。隨着異常類型列表的增長,通過更改代碼來防止每個新的異常類型,或爲該異常類型添加新的catch。

在Web服務中,您可以創建自定義異常,並將其作爲節點添加到Web服務將提供的一般異常中。

在您的代碼示例中,我不會使用try ... catch,除非您預計會發生異常並且您知道如何處理它。

如何處理在較低層的異常。我應該讓這個例外冒出來嗎?

是的。

+0

謝謝你。非常直截了當。如果我想在網絡應用程序的最高級別捕捉。我會捕捉什麼樣的例外。任何地方讀取狀態不會捕獲類型異常的例外 –

+0

@Richard:我已更改文字以回答您的評論。 – RoadWarrior

+0

好聽起來不錯。如果我想捕獲一個sqlexception並且我想在UI中捕獲它,我需要添加對包含異常類型的名稱空間的引用。這似乎是正確的 –

1

好吧,這將是過於短暫的,因爲它仍然是早在這裏的早晨,但我一直在這個同樣的問題所以在這裏掙扎是這麼理解的:

「只處理可以恢復的異常從「

我的理解是,你得到了一個例外,在你的代碼中你可以做些什麼。在低級代碼的情況下,您可以讓異常冒泡回到可以修改「進程」來處理異常並可能再次嘗試該進程的層中。 (我通常將錯誤記錄在投入的地方。)

+0

爲了擴展Nitax的答案,例如你不會嘗試處理系統內存不足時引發的OutOfMemoryException,而是會崩潰,嘗試保存用戶作品並優雅地退出應用程序。 –

+0

一般很好的建議,除了最後一點。如果你只是想記錄它,你應該儘可能在最高級別(例如用戶界面)下執行它,否則你最終會得到散佈在代碼中的錯誤記錄的代碼。如果你只是讓它們全部冒泡,那麼你可以有一個頂級的通用錯誤處理程序來記錄任何未處理的異常。 –

+0

@DylanSmith這實際上是一個很好的觀點。我剛剛使用這種方法編寫代碼,因爲我爲我的代碼的不同區域定義了不同的Traces。這樣,日誌被寫入正確的Trace ... – Nitax

2

一些簡單的基本規則:

  • 處理異常需要你的程序的狀態是正是因爲它的代碼之前開始了導致異常相同。您將需要大量的捕獲和最終塊來將變量恢復到初始狀態。

  • 只有在捕獲異常時才考慮處理異常,從而允許程序以有意義的方式繼續運行。例如,當數據庫服務器脫機時,很難做任何有用的事情,不妨停止該程序。

  • 如果您需要人工採取糾正措施(您幾乎總是這樣做),那麼請確保她有足夠的信息來解決問題。讓異常起泡到UI層。避免解釋異常(例如,「無法更新數據庫」),顯示確切的異常消息和堆棧跟蹤。

  • 爲AppDomain.CurrentDomain.UnhandledException實現處理程序,並記錄或顯示e.ExceptionObject的值。有助於診斷未處理的異常。並幫助您避免在任何地方捕捉到。

  • 具有良好的診斷一百未處理的異常是不是一個抓一個不穩定的程序,所以它會產生壞的數據或導致引發其他無關的異常更好。

+0

當然,你不會顯示用戶的堆棧跟蹤。沒有這種安全風險! –

+0

當然不是,你在說什麼? –