|
|
|
|
|
|
異常處理是我們代碼的一個非常重要的方面。我們經常可以看到在代碼庫中重復的一種模式是捕獲異常,在本地處理它,然后將其重新拋給更高級別的組件。
重新拋出步驟是我們很容易犯錯誤的地方:
try
{
await GetBlogsFromApi();
}
catch (HttpRequestException e)
{
throw e;
}
你知道當我們重新拋出這樣的異常時會出現什么問題嗎?
在throw e;語句中,表達式的結果e必須可隱式轉換為System.Exception。
你可以使用內置異常類,例如ArgumentOutOfRangeException或InvalidOperationException。.NET 還提供了在特定條件下拋出異常的輔助方法:ArgumentNullException.ThrowIfNull和ArgumentException.ThrowIfNullOrEmpty。你還可以定義自己的派生自System.Exception 的異常類。
異常的堆棧跟蹤被重寫到我們明確重新拋出它的代碼行,這意味著我們首先丟失了有關導致異常的原因的所有有價值的信息,這會使調試代碼變得非常困難。
但是,我們可以很容易地解決這個問題。
在catch塊內,你可以使用throw;語句重新拋出塊處理的異常catch:
try
{
await GetBlogsFromApi();
}
catch (HttpRequestException e)
{
throw;
}
當我們這樣做時,異常會在保留原始堆棧跟蹤的同時重新拋出,我們現在首先保存有關導致異常的原因的所有有價值的信息,我們調試代碼并找出問題所在會容易得多。
注意throw;保留異常的原始堆棧跟蹤,它存儲在Exception.StackTrace屬性中,與此相反,throw e;更新 的StackTrace屬性e。
拋出異常時,公共語言運行庫 (CLR) 會查找可以處理此異常的catch塊。如果當前執行的方法不包含這樣的catch塊,CLR 會查看調用當前方法的方法,依此類推調用堆棧。如果沒有catch找到塊,CLR 將終止正在執行的線程。
相關文章
