错误处理

在使用SDK访问日志服务端时,可能会出现网络中断、网络延迟导致的请求失败。本文介绍SDK请求失败时的错误处理逻辑。

错误类型及处理原则

SDK可能出现的异常错误可以分成如下几类:

  • 由日志服务端返回的错误。这类错误由日志服务端返回并由SDK处理。关于这类错误的详细信息可以参见具体的API接口说明、API错误码。关于错误码的更多信息,请参见错误码

  • 由SDK在向服务端发出请求时出现的网络错误。这类错误包括网络连接不通,服务端返回超时等。

  • 由SDK自身产生的、与平台及语言相关的错误,如内存溢出等。

目前,各个语言SDK的实现都采取抛出异常的方式处理错误。具体原则如下:

  • 由日志服务端返回的错误或者由SDK在向服务端发出请求时出现的网络错误将会被SDK处理并包装在统一的LogException类抛出给用户处理。

  • 由SDK自身产生的、与平台及语言相关的错误不会被SDK处理,而是直接抛出平台及语言的Native Exception类给用户处理。

LogException

LogException类是SDK定义的、用于处理日志服务自身逻辑错误的异常类。它继承自各个语言的异常基类,提供如下异常信息:

  • 错误代码(Error Code):标示错误类型。如果是来自服务端的返回错误,则这个错误代码与API返回的错误代码一致。如果是SDK网络请求错误,则其错误代码为RequestError 。具体请参见各个语言的完整API参考。

  • 错误消息(Error Message):标示错误消息。如果是来自服务端的响应错误,则这个错误消息与API返回的错误消息一致。如果是SDK网络请求错误,则其错误消息为request is failed.。具体请参见各个语言的完整API参考。

  • 错误请求ID(Request Id):标示当前错误对应于服务端的请求ID。该ID只有在服务端返回错误消息时有效,否则为空字符串。用户可以在遇到错误请求时记下该请求ID并提供给日志服务团队进行问题追踪和定位。

请求失败与重试

在使用SDK访问日志服务端时,有可能会因为网络临时中断、传输延时过程、服务端处理过慢等一系列原因导致请求失败。目前,这类错误都直接以异常抛出,日志服务内部并未对此做任何重试逻辑。所以,您在使用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
# 其他代码。