4

我有一個WCF svc分爲服務層,業務邏輯層和數據訪問層。在哪裏捕捉異常

當我的DAL遇到異常時,我應該在那裏捕捉它還是讓它回滾到服務層?爲什麼?

請忽略此場景的任何客戶參與,我只關心在WCF svc上記錄異常。

回答

3

這也取決於您如何構建解決方案。例如,如果DAL和BLL圖層是完全獨立的組件,那麼他們不能對誰調用它們做出假設。因此,他們都應該在組件邊界上捕獲異常,記錄這些異常,然後允許異常傳播。他們可能想包裝的一般例外層特定的例外:

catch (Exception ex) 
{ 
    Logger.Log(ex); 
    throw new DalException("Unhandled exception in DAL", ex); 
} 

如果您知道這些只會被用來作爲整個應用程序的一部分,那麼你可以推遲記錄到的最外層 - 的層,如果它不捕獲異常,則不會記錄該異常。

4

有一個術語 - 異常屏蔽。基本上你應該防止系統異常走向更高層次,因爲這可能會給系統架構一個視圖。 WCF異常屏蔽可以捕獲某些類型的異常,並將其替換爲其他類型的異常。例如,它可以捕獲StackOverflow異常並將其替換爲您的自定義SystemException。如果您使用的企業庫,你也可以配置爲記錄這些例外,當他們被替換

Using the Exception Handling Block in Enterprise Library 3.0

3

我想這取決於服務是如何消耗和誰(如果任何人)要意識到,當一個異常發生。例如,如果您正在開發任務關鍵型內部業務應用程序,則可能需要將異常的詳細信息通過服務層鼓泡到消耗應用程序的用戶界面,以便最終用戶可以聯繫開發人員可以快速解決問題。

但是,假設您的服務被公共網頁佔用。您可能仍希望服務層以某種方式捕獲錯誤,但您可能選擇將最少的信息傳遞給最終客戶端,向最終用戶提供一般錯誤消息,並將該例外的詳細信息寫入錯誤日誌開發人員審查。最後,我仍然認爲你想讓這個異常冒泡到服務層,但是你如何處理異常並決定傳遞給最終客戶端的信息取決於你。

1

我通常使用通過配置文件中的ServiceBehavior附加到Web服務的通用錯誤處理程序(System.ServiceModel.Dispatcher.IErrorHandler實現)。

IErrorHandler.ProvideFault方法截取例外從服務拋出:

  • 記錄它們;

  • 通過按原樣傳遞FaultExceptions;

  • 將BLL拋出的「業務」異常(例如業務規則違例)轉換爲帶有錯誤代碼「sender/client」的FaultExceptions;

  • 將故障代碼爲「receiver/server」的技術異常(例如由DAL拋出)轉換爲FaultExceptions。

通過這種方式,服務代碼本身只包含業務代碼,並且不需要捕獲任何異常。