在使用SDK訪問Log Service端時,可能會出現網路中斷、網路延遲導致的請求失敗。本文介紹SDK請求失敗時的錯誤處理邏輯。
錯誤類型及處理原則
SDK可能出現的異常錯誤可以分成如下幾類:
由Log Service端返回的錯誤。這類錯誤由Log Service端返回並由SDK處理。關於這類錯誤的詳細資料可以參見具體的API介面說明、API錯誤碼。關於錯誤碼的更多資訊,請參見錯誤碼。
由SDK在向服務端發出請求時出現的網路錯誤。這類錯誤包括網路連接不通,服務端返回逾時等。
由SDK自身產生的、與平台及語言相關的錯誤,如記憶體溢出等。
目前,各個語言SDK的實現都採取拋出異常的方式處理錯誤。具體原則如下:
由Log Service端返回的錯誤或者由SDK在向服務端發出請求時出現的網路錯誤將會被SDK處理並封裝在統一的LogException類拋出給使用者處理。
由SDK自身產生的、與平台及語言相關的錯誤不會被SDK處理,而是直接拋出平台及語言的Native Exception類給使用者處理。
LogException
LogException類是SDK定義的、用於處理Log Service自身邏輯錯誤的異常類。它繼承自各個語言的異常基類,提供如下異常資訊:
錯誤碼(Error Code):標示錯誤類型。如果是來自服務端的返回錯誤,則這個錯誤碼與API返回的錯誤碼一致。如果是SDK網路請求錯誤,則其錯誤碼為
RequestError
。具體請參見各個語言的完整API參考。錯誤訊息(Error Message):標示錯誤訊息。如果是來自服務端的響應錯誤,則這個錯誤訊息與API返回的錯誤訊息一致。如果是SDK網路請求錯誤,則其錯誤訊息為
request is failed.
。具體請參見各個語言的完整API參考。錯誤請求ID(Request Id):標示當前錯誤對應於服務端的請求ID。該ID只有在服務端返回錯誤訊息時有效,否則為空白字串。使用者可以在遇到錯誤請求時記下該請求ID並提供給Log Service團隊進行問題追蹤和定位。
請求失敗與重試
在使用SDK訪問Log Service端時,有可能會因為網路臨時中斷、傳輸延時過程、服務端處理過慢等一系列原因導致請求失敗。目前,這類錯誤都直接以異常拋出,Log Service內部並未對此做任何重試邏輯。所以,您在使用SDK時需要自己定義相應的處理邏輯(重試請求或者直接報錯等)。
樣本
假設您需要訪問華東1(杭州)地區下名字為big-game的Project,且在出現網路異常時主動重試指定次數。各語言的程式碼片段如下:
// 其他代碼。
// 本樣本從環境變數中擷取AccessKey ID和AccessKey Secret。
String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
String project = "big-game";
String endpoint = "cn-hangzhou.sls.aliyuncs.com";
int max_retries = 3;
/*
* 構建一個Client。
*/
Client client = new Client(accessId, accessKey, endpoint);
ListLogStoresRequest lsRequest = new ListLogStoresRequest(project);
for (int i = 0; i < max_retries; i++)
{
try
{
ListLogStoresResponse res = client.ListLogStores(lsRequest);
//處理返回的Response。
break;
}
catch(LogException e)
{
if (e.GetErrorCode() == "RequestError")
{
if ( i == max_retries - 1)
{
System.out.println("request is still failed after all retries.");
break;
}
else
System.out.println("request error happens, retry it!");
}
else
{
System.out.println("error code :" + e.GetErrorCode());
System.out.println("error message :" + e.GetErrorMessage());
System.out.println("error requestId :" + e.GetRequestId());
break;
}
}
catch(Exception ex)
{
System.out.println("unrecoverable exception when listing logstores.");
break;
}
}
// 其他代碼。
// 其他代碼。
// 本樣本從環境變數中擷取AccessKey ID和AccessKey Secret。
String accessId = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKey = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
String project = "big-game";
String endpoint = "cn-hangzhou.sls.aliyuncs.com";
int max_retries = 3;
// 建立一個Client。
SLSClient client = new SLSClient(endpoint, accessId, accessKey);
ListLogstoresRequest request = new ListLogstoresRequest();
request.Project = project;
for (int i = 0; i < max_retries; i++)
{
try
{
ListLogstoresResponse response = client.ListLogstores(request);
//處理返回的Response。
break;
}
catch(LogException e)
{
if (e.errorCode == "SLSRequestError")
{
if ( i == max_retries - 1)
{
Console.Writeline(“request is still failed after all retries.”);
break;
}
else
{
Console.Writeline("request error happens, retry it!");
}
}
else
{
Console.Writeline("error code :" + e.errorCode);
Console.Writeline("error message :" + e.Message);
Console.Writeline("error requestId :" + e.RequestId);
break;
}
}
catch(Exception ex)
{
Console.Writeline("unrecoverable exception when listing logstores.");
break;
}
}
// 其他代碼。
<?php
// 其他代碼。
$endpoint = 'cn-hangzhou.sls.aliyuncs.com';
// 本樣本從環境變數中擷取AccessKey ID和AccessKey Secret。
$accessId = getenv('ALIBABA_CLOUD_ACCESS_KEY_ID');
$accessKey = getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
$maxRetries = 3;
// 構建一個Client。
$client = new Aliyun_Sls_Client($endpoint, $accessId, $accessKey);
$project = 'big-game';
$request = new Aliyun_Sls_Models_ListLogstoresRequest($project);
for($i = 0; $i < $maxRetries; ++$i)
{
try
{
$response = $client->ListLogstores($request);
// 處理返回的Response。
break;
}
catch (Aliyun_Sls_Exception $e)
{
if ($e->getErrorCode()=='RequestError')
{
if ($i+1 == $maxRetries)
{
echo "error code :" . $e->getErrorCode() . PHP_EOL;
echo "error message :" . $e->getErrorMessage() . PHP_EOL;
break;
}
echo 'request error happens, retry it!' . PHP_EOL;
}
else
{
echo "error code :" . $e->getErrorCode() . PHP_EOL;
echo "error message :" . $e->getErrorMessage() . PHP_EOL;
echo "error requestId :" . $e->getRequestId() . PHP_EOL;
break;
}
}
catch (Exception $ex)
{
echo 'unrecoverable exception when listing logstores.' . PHP_EOL;
var_dump($ex);
break;
}
}
// 其他代碼。
from aliyun.log import LogClient, ListLogstoresRequest, LogException;
# 其他代碼。
from aliyun.log.logclient import xrange
endpoint = 'cn-hangzhou.log.aliyuncs.com'
# 本樣本從環境變數中擷取AccessKey ID和AccessKey Secret。
accessId = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID', '')
accessKey = os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET', '')
maxRetries = 3
# 構建一個Client。
client = LogClient(endpoint, accessId, accessKey)
project = 'big-game'
lsRequest = ListLogstoresRequest(project)
for i in xrange(maxRetries):
try:
res = client.ListLogstores(lsRequest)
# 處理返回的Response。
break
except LogException as e:
if e.get_error_code() == "RequestError":
if i+1 == maxRetries:
print("error code :" + e.get_error_code())
print("error message :" + e.get_error_message())
break
else:
print("request error happens, retry it!")
else:
print("error code :" + e.get_error_code())
print("error message :" + e.get_error_message())
print("error requestId :" + e.get_request_id())
break
except Exception as ex:
print("unrecoverable exception when listing logstores.")
break
# 其他代碼。