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