Error handling

更新时间:
复制 MD 格式

The Tablestore Go software development kit (SDK) uses exceptions to handle errors. This topic describes how Tablestore handles errors, the information that exceptions contain, and the available retry policies.

Method

The Tablestore Go SDK throws an exception when an error occurs. An API call is successful if it does not throw an exception. Otherwise, the operation has failed.

Note

For batch operations, such as BatchGetRow and BatchWriteRow, you must check not only for exceptions but also for the status of each row. The entire API call is successful only when all rows are processed successfully.

Exceptions

When you use the Tablestore Go SDK, an exception is usually returned as the second parameter of a method's return value. Therefore, before you retrieve the returned data, check whether the err parameter has a value.

If a server-side error occurs in Tablestore, the err parameter contains a requestId. The `requestId` is a universally unique identifier (UUID) that uniquely identifies the request. If you cannot resolve the issue, record this requestId and submit a ticketor join the DingTalk group 36165029092 (Tablestore Technical Support Group 3) for assistance.

The following code provides an example of how to handle exceptions:

client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
listTables, err := client.ListTable()
if err != nil {
    // Handle the exception.
    fmt.Println(err.Error())
} else {
    // No exception.
    for _, table := range listTables.TableNames {
        fmt.Println("TableName: ", table)
    }
}

Retries

The Go SDK provides a default retry policy. You can also customize the retry logic.

Default retry policy

The Go SDK performs a backoff retry when a throttling error or a server-side internal error occurs during a read operation. The default maximum number of retries is 10, and the default maximum total retry duration is 5 seconds. You can modify tablestore.TableStoreConfig to set the parameters for the default retry policy. The following table describes the parameters.

Parameter

Description

Default value

RetryTimes

The maximum number of retries.

10

MaxRetryTime

The maximum total duration for retries.

5s

DefaultRetryInterval

The jitter value for the exponential backoff retry policy. This prevents multiple failed clients from initiating retry requests at the same time.

10 ms

MaxRetryInterval

The maximum time interval between two retries.

320 ms

Transport

Manages the underlying transport properties of the HTTP client. The default value is nil.

If you set this parameter, the `HTTPTimeout.ConnectionTimeout`, `MaxIdleConnections`, and `IdleConnTimeout` parameters do not take effect.

nil

HTTPTimeout.ConnectionTimeout

The timeout duration for establishing a new HTTP network connection.

15s

HTTPTimeout.RequestTimeout

The maximum time an HTTP client waits for a server response after sending a request.

30s

MaxIdleConnections

The maximum number of idle connections for an HTTP host.

2000

IdleConnTimeout

The maximum duration an idle connection for an HTTP host remains open in the connection pool without being reused.

25s

Custom retry logic

To modify the default retry logic or create a custom retry logic, you can set the following parameters for TableStoreClient.

Parameter

Description

Default value

CustomizedRetryFunc

If you set CustomizedRetryFunc, the SDK first checks this method to determine whether to perform a retry.

  • If `CustomizedRetryFunc` is not set (is nil), the SDK executes the default retry logic.

  • If `CustomizedRetryFunc` is not nil and determines that a retry is needed, the SDK performs a retry based on the custom retry logic.

  • If `CustomizedRetryFunc` is not nil and determines that a retry is not needed, the SDK checks the value of KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc for further action.

    • If KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc is false, no retry is performed.

    • If KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc is true, the SDK then checks the default retry logic to determine whether to perform a retry.

nil

KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc

true

The following examples show how to customize the retry logic:

Retry all errors

The following example shows how to retry all errors.

func alwaysRetry(errorCode string, errorMsg string, action string, httpStatus int) bool {
	return true
}
func main() {
    client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
  	client.CustomizedRetryFunc = alwaysRetry
    // do something
}

Do not retry any errors

The following example shows how to disable retries for all errors.

func alwaysNotRetry(errorCode string, errorMsg string, action string, httpStatus int) bool {
	return false
}
func main() {
    client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
  	client.CustomizedRetryFunc = alwaysNotRetry
    client.KeepDefaultRetryStrategyWhileUsingCustomizedRetryFunc = false
    // do something
}

Callback on retry

To perform predefined operations when the SDK retries an operation, you can set the following parameter for TableStoreClient.

Parameter

Description

Default value

RetryNotify

The callback method that is triggered when the SDK performs a retry.

nil

The following example shows how to set a business-side trace ID for each request and print this trace ID when a retry occurs.

func userRetryNotify(traceId, requestId string, err error, action string, backoffDuration time.Duration) {
    // Custom logic that is invoked when a retry is triggered.
    fmt.Println("Retry for traceId: " + traceId + ", timestamp: " + strconv.FormatInt(time.Now().UnixNano(), 10))
}

func alwaysRetry(errorCode string, errorMsg string, action string, httpStatus int) bool {
    return true
}

func main() {
    client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
    client.CustomizedRetryFunc = alwaysRetry
    client.RetryNotify = userRetryNotify

    request := &tablestore.DescribeTableRequest{TableName: "tableNotExist"}
    // Set the business-side trace ID for the request.
    request.ExtraRequestInfo.SetTraceID("test_TraceId_" + strconv.FormatInt(time.Now().UnixNano(), 10))
    // do something
    res, err := client.DescribeTable(request)

    if err != nil {
        fmt.Println(err.Error())
    } else {
        fmt.Println(res.ResponseInfo.RequestId)
    }
}

The following output is an example:

Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752655394000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752683437000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752708603000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752760519000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752814590000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097752916539000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097753110943000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097753454311000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097753798531000
Retry for traceId: test_TraceId_1711097752255675000, timestamp: 1711097754165411000
OTSObjectNotExist Requested table does not exist. 0006143b-fdd6-5050-10ef-700b045590fc