1. 程式人生 > >【轉】編寫高質量代碼改善C#程序的157個建議——建議60:重新引發異常時使用Inner Exception

【轉】編寫高質量代碼改善C#程序的157個建議——建議60:重新引發異常時使用Inner Exception

開發 網絡連接 方便 額外 write com ket 捕獲 分布式系

建議60:重新引發異常時使用Inner Exception

當捕獲了某個異常,將其包裝或重新引發異常的時候,如果其中包含了Inner Exception,則有助於程序員分析內部信息,方便代碼調試。

以一個分布式系統為例,在進行遠程通信的時候,可能會發生的情況肯能會有:

1)網卡被禁用或者網線斷開,此時會拋出SocketException,消息問:“由於目標機器積極拒絕,無法連接。”

2)網絡正常,但是要鏈接的目標主機沒有端口沒有處在監聽狀態,此時會拋出SocketException,消息為:“由於連接方在一段時間後沒有正確答復或連接的主機沒有反應,連接嘗試失敗。”

3)鏈接超時,此時需要通過代碼實現關閉鏈接,並拋出SocketException,消息為:“鏈接超過約定的時長。”

發生以上三種情況的任何一種情況,在返回給最終用戶的時候,我們都需要將異常信息包裝成為“網絡連接失敗,請稍後再試”。

所以,一個分布式系統的業務處理方法,看起來應該是這樣的:

            try
            {
                SaveUser(user);
            }
            catch (SocketException ex)
            {
                throw new CommunicationFailureException("網絡連接失敗,請稍後再試", ex);
            }

在提示這條信息的時候,我們可能需要將原始異常記錄到日誌裏,以供開發者分析具體原因(如果這種情況頻繁出現,就可能是一個Bug)。在記錄日誌時,非常有必要記錄此異常出現的內部異常或是堆棧信息。

throw new CommunicationFailureException("網絡連接失敗,請稍後再試", ex);就是將異常包裝成為一個CommunicationFailureException,並將SocketException作為InnerException(即ex)向上傳遞。

如果不打算使用InnerException,但是要返回一下額外的信息,可以使用Exception的Data屬性。如下:

            try
            {
                SaveUser(user);
            }
            catch (SocketException ex)
            {
                ex.Data.Add("SocketInfo","網絡連接失敗,請稍後再試");
                throw ex;
            }

在上層進行捕獲的時候,可以通過鍵值來得到異常信息:

            catch (SocketException ex)
            {
                Console.WriteLine(ex.Data["SocketInfo"]);
            }

轉自:《編寫高質量代碼改善C#程序的157個建議》陸敏技

【轉】編寫高質量代碼改善C#程序的157個建議——建議60:重新引發異常時使用Inner Exception