我工作的n層應用程序,只有在我的表現層做的try/catch n層。如果數據層或業務層發生錯誤,則此錯誤將由我的表示層中的try/catch捕獲。這是好的,還是我應該嘗試捕捉每一層的每種方法?使用嘗試捕捉
使用嘗試捕捉
回答
這裏是要避免在任何層面的內容:一堆方法,所有看起來像這樣:
void method()
{
try
{
// some code here that may potentially throw an exception
}
catch (/* anything here */)
{
// code right here to handle that exception
}
}
如果這是你在做什麼這樣做,你可能會回到VB的舊版本On Error Goto
系統,因爲你還沒有獲得任何東西。異常爲錯誤處理提供了兩個主要優勢:以不同方式輕鬆處理不同類型錯誤的能力,以及在程序調用堆棧中進一步捕獲錯誤的能力。這是你在這裏問的第二個優點。
因此,我們看到您確實希望允許異常「向上冒泡」到更高層,因爲它是我們爲什麼總是有例外的很大一部分......但是您是否總想在表示層處理它們?不,我們可以做得更好。有時,可能存在關於如何響應來自數據層的某些例外的業務規則。有時,數據層本身可能能夠處理異常並從異常中恢復,而不用提醒其上方的圖層。另一方面,例外的一個優點是它可以讓你在較低的層次上編寫較簡單的代碼,並且對於錯誤處理代碼而言,正常的程序執行流程的中斷更少。這樣做的代價是將更多的try/catch放置在表示層中。同樣,這並不意味着表示層是處理它們的唯一地方,但是這是確保它們不會越過未捕獲到表示層的努力的地方。如果您無法在其他地方處理它們,請確保您有方法在表示層捕獲它們,並以友好的方式將它們展示給用戶。使用相同的機制記錄或報告您的異常也是一個好主意,因此您可以獲得有關應用程序失敗的良好指標,然後使用該信息使您的應用程序更好。
當你確實處於最後一個異常處理程序中時,你可能還想考慮終止應用程序。如果你真的有意想不到的事情發生,如未處理的異常通過表示層,那麼有一個有效的思想流派,表明繼續運行該程序可能不是一個好主意。但即使在這種情況下,您也需要捕捉並嘗試報告異常,然後儘可能優雅地崩潰。
在一般情況下,最好是捕捉儘可能接近它發生在哪裏,讓您的代碼可能做一些事情來修復/調整/反應問題的異常。這個「做什麼」取決於情況。例如,如果您的服務層呼叫失敗,則可能需要重試呼叫,因爲該服務可能太忙;而如果你的存儲過程被破壞了,那麼你重試多少次並不重要,它會被打破,直到數據庫中的邏輯被糾正。
如果你想要做的是錯誤日誌,然後抓住儘可能接近它發生在哪裏的錯誤是那麼有用。
我曾經工作過的每一個項目必須在應用程序的每一層try-catch
塊。
try-catch
的推論是Fail Fast的概念,它通常表示當系統立即失敗而不是緩慢失敗時(讀取:數小時,數天,數週,數月甚至數年的操作),調試生產力會增加。
在.NET Framework快速失敗的一個很好的例子是Convert.ToInt32()
使用相對於一個直線上升鑄造使用(int)
,像這樣:
int? settingValue = Convert.ToInt32(SomeSettingString);
if(settingValue == null)
{
// Do something here
}
else
{
// Do something else here
}
如果SomeSettingString
可以轉換爲一個int
,則該值被設置爲和Do something else
邏輯被執行。假設從現在開始一年後,設置發生變化並返回null
,因爲轉換失敗,現在突然邏輯執行,並且發現這種情況是一種調試冒險,如果您能發現的話。像這樣的大多數問題似乎只發生在PRODUCTION而不是DEV。
現在讓我們來看看同樣的事情,但由於沒有快,就像這樣:
try
{
int settingValue = (int)SomeSettingString;
}
catch(Exception ex)
{
// Fail fast and throw exception
throw new Exception("Fail fast");
}
現在發生異常時立即設置字符串導致一個轉換到int
失敗。
注意:要注意的是未能快速通過空catch
塊被破壞的是「吃」的例外。應避免try
塊空catch
塊,因爲它們不可避免地導致了「吃」的例外情形。
不要這樣做:
try
{
// Exception waiting to happen here
}
catch(Exception ex)
{
// Catch-all, because all exceptions derive from Exception class
// So this will eat exceptions and pretend like they never happened
}
- 1. 嘗試捕捉
- 2. 嘗試捕捉
- 3. 與嘗試捕捉
- 4. $就嘗試捕捉
- 5. Elixir嘗試捕捉
- 6. 嘗試捕捉塊不捕捉?
- 7. 驗證輸入使用嘗試捕捉
- 8. 如何使用,甚至嘗試捕捉
- 9. 如何使用嘗試捕捉
- 10. 嘗試捕捉異常?
- 11. 嘗試捕捉執行
- 12. 嘗試捕捉性能c#
- 13. 嘗試捕捉細節
- 14. 嘗試捕捉掃描儀
- 15. TaskContinuationOptions.OnlyOnFaulted VS嘗試捕捉
- 16. 嘗試捕捉問題
- 17. C++嘗試捕捉做法
- 18. 嘗試捕捉語句realBasic
- 19. 問題與嘗試捕捉
- 20. 嘗試捕捉404錯誤
- 21. Powershell的嘗試捕捉
- 22. 不能在嘗試捕捉
- 23. 嘗試抓住 - 不捕捉
- 24. 嘗試捕捉在Java
- 25. 嘗試,捕捉問題
- 26. 嘗試捕捉問題
- 27. 嘗試捕捉恢復
- 28. 嘗試不捕捉WebException
- 29. Java嘗試/捕捉方法
- 30. 嘗試捕捉異常
處理異常時,只要您能夠繼續執行代碼,即使出現錯誤,無論發生什麼層次。 – Servy