呼叫異常時
透過 SDK 呼叫 UOF X 時,可能會發生一些異常情況,其異常情況可以分成兩類:
- 預期中的錯誤: 會有錯誤代碼
- 非預期的錯誤: 不會有錯誤代碼,僅會有錯誤訊息
使用 try catch 去攔截異常¶
在 SDK 開發中,不管是哪種錯誤,都會以 exception 的模式回傳,因此在程式碼中,請使用 try catch
去接住每個異常:
//設定金鑰
UofxService.Key = "xxx";
//設定 UOF X 站台網址
UofxService.UofxServerUrl = "https://myuofx.com.tw";
//使用 try catch 接住異常的情形
try{
//呼叫建立部門
await UofxService.BASE.Department.Create(...);
}catch(exception e){
...
}
轉換 Exception 成可讀性更高的 Model¶
不管是預期中或非預期的錯誤,都會將錯誤資訊放在 exception 物件中,我們在 SDK 中提供了轉換的方法,可以將其轉成更容易判斷的結構,接著繼續修正上面的程式碼,在 catch 中加入轉換的方法如下:
//設定金鑰
UofxService.Key = "xxx";
//設定 UOF X 站台網址
UofxService.UofxServerUrl = "https://myuofx.com.tw";
//使用 try catch 接住異常的情形
try{
//呼叫建立部門
await UofxService.BASE.Department.Create(...);
}catch(exception e){
//將 exception 轉換成較容易判斷的 model
var model = UofxService.Error.ConvertToModel(e);
//將 model 轉成 json 格式印出
Console.WriteLine(UofxService.Json.Convert(model));
}
在上面的程式碼中,UofxService.Error.ConvertToModel(e)
會將 exception 轉成 ExceptionModel
,ExceptionModel 包含了下列屬性:
public class ExceptionModel
{
/// <summary>
/// 錯誤的類型
/// </summary>
public ErrorType Type { get; }
public string Message { get; }
public IEnumerable<MoreErrorItem> Errors { get; }
}
在 預期中的錯誤 情況下,錯誤代碼會存放在 Errors
屬性中,相反的在 非預期的錯誤 情況下,Errors
會是 null,而原 exception 的 message 會存放在 Message
屬性中。在你的程式碼中,可以透過檢查 Type 屬性來確認是哪種錯誤類型,進一步的做相關的處置。
public enum ErrorType
{
/// <summary>
/// 已知的錯誤,會有錯誤代碼
/// </summary>
ErrorCodes = 0,
/// <summary>
/// 預期外的錯誤,只會有錯誤訊息
/// </summary>
Exception = 99
}
支援 AggregateException 轉換¶
如果在呼叫 SDK 非同步方法時,不是用 await
等待回應,而是用 Wait()
、WaitAll()
或 WaitAny()
來等待 SDK 回應,則異常時會回拋 AggregateException
物件,我們也有提供相對應的方法來轉換:
//設定金鑰
UofxService.Key = "xxx";
//設定 UOF X 站台網址
UofxService.UofxServerUrl = "https://myuofx.com.tw";
try{
//呼叫建立部門
var myTask = UofxService.BASE.Department.Create(...);
myTask.Wait();
}catch(AggregateException e){
//models 的型態會是 List<ExceptionModel>
var models = UofxService.Error.ConvertToModel(e);
//將 model 轉成 json 格式印出
Console.WriteLine(UofxService.Json.Convert(model));
}
須注意的是,回傳的 Model 是 ExceptionModel
的集合。
應該避免使用
Wait()
、WaitAll()
或 WaitAny()
的方式會將原本的 exception 封裝在 AggregateException
物件中,這會導致異常判讀難度增加,並且大幅提升處理的複雜度。因此除非有特殊的需求,否則應避免使用這些方法,通常還是建議使用 await
。