[英]Managing exceptions in a .NET client library for a web API
我正在為公共Web API構建.NET客戶端庫。 我苦苦掙扎的事情之一是如何最好地向庫用戶指示錯誤情況。 顯然,當執行失敗時,我的庫應該拋出異常或將異常傳遞給調用者,但是我應該使用現有的異常還是為我的庫創建新的異常? 如果創建新的例外,我應該只創建一個還是多個例外?
選項1:僅使用現有例外
在最基本的方面,例如,我可以throw new Exception("API authentication error.");
但這是非常通用的,之后需要大量處理才能處理。 我還可以使用更合適的現有異常,例如System.Security.Authentication.AuthenticationException
,但是由於所有不同的命名空間,使用該庫將很尷尬。 在某些情況下,沒有什么比InvalidOprationException
更合適的了,因此對於使用庫處理錯誤的人來說,采用這種方法似乎很麻煩。 最簡單的方法可能就是只使用HttpException
類,因為在大多數情況下,大多數錯誤情況都是HTTP狀態代碼和消息的轉換。
選項2:為每種情況創建一個例外
我還可以為每種情況創建一個例外,但是將它們全部保留在庫中。 所以我可以創建一個NotFoundException
, AuthorizationException
, TransactionsPendingException
和其他特定的異常。
選項3:為我的客戶創建一個例外
第三種選擇是創建一個自定義異常MyApiException
,其中包含針對即將出現的各種錯誤的狀態代碼(當然還有一條相應的消息)。 因此,我可能然后throw new MyApiException(401,"Not authorized.")
在我看來,選項3是最簡單的實現方法,也是調用方法最容易處理的方法。 我已經在GitHub和Codeplex上看到了使用這些選項的API客戶端。 是否有推薦的客戶端庫方法或它們都有效?
Microsoft在MSDN上擁有一些與此有關的有價值的信息:
https://msdn.microsoft.com/en-us/library/seyhszts%28v=vs.110%29.aspx
就個人而言,我傾向於執行以下操作:
在合理的情況下使用現有的例外
例如,基於密鑰的操作在傳遞無效密鑰時拋出
KeyNotFoundException
為需要的方案創建自定義例外
Either<TSuccess,TFail>
類似Either<TSuccess,TFail>
這樣的結果類型的異常
public int GetMyItem(string key)
{
if (string.IsNullOrEmpty(key)) throw new ArgumentNullException("key");
if (!_myDictionary.ContainsKey(key))
{
throw new KeyNotFoundException();
}
// Additional implementation left out
}
public class ArgumentNotOddException : ArgumentException
{
public ArgumentNotOddException(string paramName)
: base(@"The argument must be odd", paramName)
{
}
}
public class MyClass
{
public void DoSomething(int x)
{
if (x%3 == 0) throw new ArgumentNotOddException("x");
}
}
public class MyClass
{
public IEnumerable<IEither<int, string>> Divide(int left, IEnumerable<int> right)
{
foreach (var num in right)
{
if (num == 0)
{
yield return Either.Right<int, string>("cannot divide by zero");
}
yield return Either.Left<int, string>(left/num);
}
}
}
您也可以只創建一個使用異常代碼和消息的MyAppException
,但是這樣會失去表達能力,異常代碼易於輸入錯誤(除非使用枚舉),並且MyAppException
與NotFoundException
MyAppException
不同。
我最好的建議是認真考慮代碼是否應該拋出,或者返回混合結果/錯誤是否合理; 在C#中這樣做有點笨拙,但是它消除了未處理的異常的負擔,並允許您在調用代碼中更加靈活。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.