呼叫異常時
透過 SDK 呼叫 UOF X 時,可能會發生一些異常情況,我們可以將其分成兩類:
- 預期中的錯誤: 會有錯誤代碼
- 非預期的錯誤: 不會有錯誤代碼,僅會有錯誤訊息
使用 try catch 去攔截異常¶
在 SDK 開發中,不管是哪種錯誤,都會以 exception 的模式回傳,因此在程式碼中,請使用 try catch 去接住每個異常:
// 設定金鑰
UofxService.Key = "xxx";
// 設定公司代碼
UofxService.CorpCode = "ooo";
// 設定 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";
// 設定公司代碼
UofxService.CorpCode = "ooo";
// 設定 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 轉成 ErrorModel,ErrorModel 包含了下列屬性:
public class ErrorModel
{
/// <summary>
/// 錯誤代碼
/// </summary>
public string ErrorCode { get; set; }
/// <summary>
/// 錯誤訊息,或多重錯誤物件
/// </summary>
public IList<ErrorEx> ErrorExpando { get; set; }
public IEnumerable<MoreErrorItem> Errors { get; }
}
public class ErrorEx
{
/// <summary>
/// 詳細的錯誤代碼
/// </summary>
public string Error { get; set; }
/// <summary>
/// 錯誤代碼的額外訊息
/// </summary>
public object ExpandoObject { get; set; }
}
在 預期中的錯誤 情況下,錯誤代碼會存放在 ErrorCode 屬性中,而更詳細的錯誤資訊則會放在 ErrorExpando 屬性中,相反的在 非預期的錯誤 情況下,ErrorCode 會是 UnknownError,而原 exception 的 message 會存放在 ErrorExpando 屬性中。
您可以從 錯誤代碼表 找到每個錯誤代碼的說明。
您可以從 格式化Exception訊息 查看方法與物件的規格。
支援 AggregateException 轉換¶
如果在呼叫 SDK 非同步方法時,不是用 await 等待回應,而是用 Wait()、WaitAll() 或 WaitAny() 來等待 SDK 回應,則異常時會回拋 AggregateException 物件,我們也有提供相對應的方法來轉換:
// 設定金鑰
UofxService.Key = "xxx";
// 設定公司代碼
UofxService.CorpCode = "ooo";
// 設定 UOF X 站台網址
UofxService.UofxServerUrl = "https://myuofx.com.tw";
try{
// 呼叫建立部門
var myTask = UofxService.BASE.Department.Create(...);
myTask.Wait();
}catch(AggregateException e){
// models 的型態會是 List<ErrorModel>
var models = UofxService.Error.ConvertToModel(e);
// 將 model 轉成 json 格式印出
Console.WriteLine(UofxService.Json.Convert(model));
}
須注意的是,回傳的 Model 是 ErrorModel 的集合。
應該避免使用
Wait()、WaitAll() 或 WaitAny() 的方式會將原本的 exception 封裝在 AggregateException 物件中,這會導致異常判讀難度增加,並且大幅提升處理的複雜度。因此除非有特殊的需求,否則應避免使用這些方法,通常還是建議使用 await。