2011-01-12 112 views
1

我正在用C#編寫一個API。我傳播的一些方法中有一些例外,因爲我希望用戶能夠看到異常。但是,有些例外,我沒有。爲了讓客戶端知道,我是否需要從該方法的每個被調用者中傳播?例如。API問題中的異常處理

一>呼叫B>調用C

,如果我從C重新拋出,做我需要從B和從做?另外,捕獲方法的catch塊(例如,從a調用的b)中的異常也將被捕獲到catch塊中。但是如果a是API的入口點並且b已經拋出了ex,那麼會有什麼區別呢?在catch塊?

謝謝

+4

**從不**寫`扔前;`。 – SLaks 2011-01-12 22:43:01

回答

2

異常處理的第一條規則:除非您知道如何處理異常,否則不要捕獲異常。使代碼看起來像catch (Exception ex) { throw ex; }毫無意義。

如果我從c重新拋出,我是否需要從b和a中做同樣的事情?不,你不這樣做。 c拋出的任何異常都會自動通過ba冒出調用堆棧並回到客戶端代碼中。另外,在一個方法的catch塊(比如,從a調用)中捕獲的異常也會被捕獲到一個catch塊中。

這是不正確的:如果b捕獲異常,a不會看到它,除非b重新拋出它。

但是,如果a是API的入口點並且b有throw ex,那麼會有什麼區別?在catch塊?

如果b發現異常然後重新拋出,則a和客戶端都會看到該異常。

順便說一下,throw ex;是不好的做法。對象跟蹤它們被拋出的調用堆棧。 throw ex;會清除此調用堆棧,從而很難調試異常的根本原因。相反,要重新拋出您捕獲的異常,請使用throw;

1

首先,你應該只捕獲一個異常,如果你打算處理它。這可以包括日誌記錄,如有必要。

如果你抓住它,但希望重新丟棄,請使用:

throw; 

throw ex; 

你也會有這種異常被捕獲每次重複。因此,您可能必須在ba之間執行此操作,例如,如果兩者都抓住它。

0

對於這個問題,「我是否需要從該方法的每個被調用方法傳播?」 答案是否定的,您不必在流程中的每個方法中都捕獲異常,最好的做法是在每次調用外部代碼時進行嘗試捕獲,在您的情況下,每次調用api。 在發現異常後,您可以:

  • 自己處理錯誤。
  • 重新拋出您創建的新自定義異常。
2

我認爲這比您試圖描述的要簡單得多:如果引發異常,它會調用堆棧直到抓取。如果沒有捕捉到,程序就會終止。如果發現異常,則由catch塊決定如何繼續。選項有:

  1. 以某種方式處理情況,不要再扔掉。在這種情況下,執行只會在catch塊之後繼續。
  2. 重新發現異常。在這種情況下,異常繼續沿着調用堆棧走,直到下一個catch塊被擊中。
  3. 拋出另一個異常:與2相同,但拋出了不同的異常。新的異常通常將原始異常保存爲內部異常。這樣,您的API的客戶端就會知道異常來自哪裏。