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.
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
| 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