0
# Error Handling and Retry
1
2
Unified exception handling and configurable retry mechanisms with exponential backoff for robust cloud service integration. The SDK provides comprehensive error information and automatic retry capabilities for transient failures.
3
4
## Capabilities
5
6
### TencentCloud SDK Exception
7
8
Main exception class providing detailed error information including error codes, messages, and request tracking identifiers for debugging and monitoring.
9
10
```python { .api }
11
class TencentCloudSDKException(Exception):
12
def __init__(self, code: str = None, message: str = None, requestId: str = None):
13
"""
14
Initialize TencentCloud SDK exception with error details.
15
16
Parameters:
17
- code (str, optional): Error code from Tencent Cloud API
18
- message (str, optional): Human-readable error description
19
- requestId (str, optional): Unique request identifier for tracking
20
"""
21
22
def get_code(self) -> str:
23
"""
24
Get the error code.
25
26
Returns:
27
str: Error code (e.g., "InvalidParameter", "AuthFailure")
28
"""
29
30
def get_message(self) -> str:
31
"""
32
Get the error message.
33
34
Returns:
35
str: Detailed error description
36
"""
37
38
def get_request_id(self) -> str:
39
"""
40
Get the request ID for tracking.
41
42
Returns:
43
str: Unique request identifier for support and debugging
44
"""
45
```
46
47
**Basic Error Handling:**
48
49
```python
50
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
51
from tencentcloud.cvm.v20170312 import cvm_client, models
52
from tencentcloud.common import credential
53
54
try:
55
cred = credential.DefaultCredentialProvider().get_credential()
56
client = cvm_client.CvmClient(cred, "ap-shanghai")
57
58
req = models.DescribeInstancesRequest()
59
resp = client.DescribeInstances(req)
60
61
print(f"Found {resp.TotalCount} instances")
62
63
except TencentCloudSDKException as err:
64
print(f"TencentCloud API Error:")
65
print(f" Code: {err.get_code()}")
66
print(f" Message: {err.get_message()}")
67
print(f" Request ID: {err.get_request_id()}")
68
69
except Exception as err:
70
print(f"Unexpected error: {err}")
71
```
72
73
**Common Error Codes and Handling:**
74
75
```python
76
def handle_tencent_cloud_error(err: TencentCloudSDKException):
77
"""Handle different types of TencentCloud errors."""
78
code = err.get_code()
79
message = err.get_message()
80
request_id = err.get_request_id()
81
82
if code == "AuthFailure":
83
print("Authentication failed - check your credentials")
84
# Could trigger credential refresh or user notification
85
86
elif code == "InvalidParameter":
87
print(f"Invalid parameter provided: {message}")
88
# Could validate and fix parameters automatically
89
90
elif code == "LimitExceeded":
91
print("API rate limit exceeded - implementing backoff")
92
# Could trigger exponential backoff
93
94
elif code == "ResourceNotFound":
95
print(f"Resource not found: {message}")
96
# Could return empty result or create resource
97
98
elif code == "InternalError":
99
print("Internal server error - retrying may help")
100
# Could trigger automatic retry
101
102
else:
103
print(f"Unhandled error {code}: {message}")
104
105
print(f"Request ID for support: {request_id}")
106
107
# Usage
108
try:
109
# API call here
110
pass
111
except TencentCloudSDKException as err:
112
handle_tencent_cloud_error(err)
113
```
114
115
### Standard Retry Mechanism
116
117
Configurable retry system with exponential backoff, jitter, and logging for handling transient failures automatically.
118
119
```python { .api }
120
class StandardRetryer:
121
def __init__(self, max_attempts: int = 3, backoff_fn = None, logger = None):
122
"""
123
Initialize standard retry mechanism.
124
125
Parameters:
126
- max_attempts (int): Maximum retry attempts (default: 3)
127
- backoff_fn (callable, optional): Custom backoff function
128
- logger (logging.Logger, optional): Logger for retry events
129
"""
130
131
def should_retry(self, exception) -> bool:
132
"""
133
Determine if an exception should trigger a retry.
134
135
Parameters:
136
- exception: Exception that occurred
137
138
Returns:
139
bool: True if retry should be attempted
140
"""
141
142
def compute_delay_before_next_retry(self, attempt: int) -> float:
143
"""
144
Calculate delay before next retry attempt.
145
146
Parameters:
147
- attempt (int): Current attempt number (1-based)
148
149
Returns:
150
float: Delay in seconds before next attempt
151
"""
152
```
153
154
**Standard Retry Configuration:**
155
156
```python
157
from tencentcloud.common import retry
158
from tencentcloud.common.profile.client_profile import ClientProfile
159
import logging
160
import sys
161
162
# Configure retry logger
163
logger = logging.getLogger("tencentcloud.retry")
164
logger.setLevel(logging.DEBUG)
165
logger.addHandler(logging.StreamHandler(sys.stderr))
166
167
# Create retry configuration
168
retryer = retry.StandardRetryer(
169
max_attempts=3, # Try up to 3 times
170
logger=logger # Log retry attempts
171
)
172
173
# Use with client profile
174
client_profile = ClientProfile()
175
client_profile.retryer = retryer
176
177
client = cvm_client.CvmClient(cred, "ap-shanghai", client_profile)
178
179
# Calls will automatically retry on transient failures
180
try:
181
response = client.DescribeInstances(models.DescribeInstancesRequest())
182
print(f"Success after retries: {response.TotalCount} instances")
183
except TencentCloudSDKException as err:
184
print(f"Failed after all retry attempts: {err.get_code()}")
185
```
186
187
**Custom Retry Backoff:**
188
189
```python
190
import random
191
import time
192
193
def custom_backoff_function(attempt):
194
"""Custom exponential backoff with jitter."""
195
base_delay = 2 ** attempt # Exponential: 2, 4, 8, 16 seconds
196
jitter = random.uniform(0, 0.1 * base_delay) # Add 10% jitter
197
return base_delay + jitter
198
199
# Use custom backoff
200
retryer = retry.StandardRetryer(
201
max_attempts=5,
202
backoff_fn=custom_backoff_function,
203
logger=logger
204
)
205
206
client_profile = ClientProfile()
207
client_profile.retryer = retryer
208
```
209
210
### No-Operation Retry
211
212
Disabled retry mechanism for scenarios requiring immediate failure feedback or when implementing custom retry logic.
213
214
```python { .api }
215
class NoopRetryer:
216
def __init__(self):
217
"""
218
Initialize no-operation retryer that never retries.
219
"""
220
221
def should_retry(self, exception) -> bool:
222
"""
223
Always returns False - no retries performed.
224
225
Returns:
226
bool: Always False
227
"""
228
229
def compute_delay_before_next_retry(self, attempt: int) -> float:
230
"""
231
Returns 0 - no delay since no retries occur.
232
233
Returns:
234
float: Always 0.0
235
"""
236
```
237
238
**No-Retry Configuration:**
239
240
```python
241
from tencentcloud.common import retry
242
243
# Disable automatic retries
244
no_retry = retry.NoopRetryer()
245
246
client_profile = ClientProfile()
247
client_profile.retryer = no_retry
248
249
# Client will fail immediately on any error
250
client = cvm_client.CvmClient(cred, "ap-shanghai", client_profile)
251
```
252
253
### Advanced Error Handling Patterns
254
255
**Retry with Circuit Breaker:**
256
257
```python
258
from tencentcloud.common.profile.client_profile import ClientProfile, RegionBreakerProfile
259
from tencentcloud.common import retry
260
import logging
261
262
# Combine retry logic with circuit breaker
263
logger = logging.getLogger("tencentcloud")
264
logger.setLevel(logging.INFO)
265
266
# Configure retries
267
retryer = retry.StandardRetryer(max_attempts=3, logger=logger)
268
269
# Configure circuit breaker for region failover
270
region_breaker = RegionBreakerProfile(
271
backup_endpoint="ap-beijing.tencentcloudapi.com",
272
max_fail_num=3,
273
timeout=30
274
)
275
276
# Combine both mechanisms
277
client_profile = ClientProfile()
278
client_profile.retryer = retryer
279
client_profile.disable_region_breaker = False
280
client_profile.region_breaker_profile = region_breaker
281
282
client = cvm_client.CvmClient(cred, "ap-shanghai", client_profile)
283
```
284
285
**Application-Level Retry Logic:**
286
287
```python
288
import time
289
import random
290
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
291
292
def robust_api_call(client, request, max_retries=3):
293
"""Application-level retry wrapper with custom logic."""
294
295
for attempt in range(max_retries + 1):
296
try:
297
response = client.DescribeInstances(request)
298
return response
299
300
except TencentCloudSDKException as err:
301
code = err.get_code()
302
303
# Don't retry on authentication or parameter errors
304
if code in ["AuthFailure", "InvalidParameter", "ResourceNotFound"]:
305
raise err
306
307
# Don't retry on final attempt
308
if attempt == max_retries:
309
raise err
310
311
# Calculate backoff delay
312
delay = (2 ** attempt) + random.uniform(0, 1)
313
print(f"Attempt {attempt + 1} failed ({code}), retrying in {delay:.2f}s...")
314
time.sleep(delay)
315
316
# Usage
317
try:
318
request = models.DescribeInstancesRequest()
319
response = robust_api_call(client, request)
320
print(f"Success: {response.TotalCount} instances")
321
except TencentCloudSDKException as err:
322
print(f"All attempts failed: {err.get_code()} - {err.get_message()}")
323
```
324
325
**Async Error Handling:**
326
327
```python
328
import asyncio
329
from concurrent.futures import ThreadPoolExecutor
330
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
331
332
async def async_api_call(client, request):
333
"""Async wrapper for synchronous SDK calls."""
334
loop = asyncio.get_event_loop()
335
336
try:
337
with ThreadPoolExecutor() as executor:
338
response = await loop.run_in_executor(
339
executor,
340
client.DescribeInstances,
341
request
342
)
343
return response
344
345
except TencentCloudSDKException as err:
346
print(f"Async API error: {err.get_code()}")
347
raise
348
349
async def parallel_api_calls(clients, request):
350
"""Make parallel API calls to multiple regions."""
351
tasks = [async_api_call(client, request) for client in clients]
352
353
try:
354
responses = await asyncio.gather(*tasks, return_exceptions=True)
355
356
for i, response in enumerate(responses):
357
if isinstance(response, TencentCloudSDKException):
358
print(f"Region {i} failed: {response.get_code()}")
359
else:
360
print(f"Region {i}: {response.TotalCount} instances")
361
362
except Exception as err:
363
print(f"Parallel execution error: {err}")
364
365
# Usage
366
regions = ["ap-shanghai", "ap-beijing", "ap-guangzhou"]
367
clients = [cvm_client.CvmClient(cred, region) for region in regions]
368
request = models.DescribeInstancesRequest()
369
370
asyncio.run(parallel_api_calls(clients, request))
371
```
372
373
**Monitoring and Alerting Integration:**
374
375
```python
376
import logging
377
import json
378
from datetime import datetime
379
380
class TencentCloudErrorHandler(logging.Handler):
381
"""Custom log handler for monitoring TencentCloud errors."""
382
383
def emit(self, record):
384
if hasattr(record, 'exc_info') and record.exc_info:
385
exc_type, exc_value, exc_tb = record.exc_info
386
387
if isinstance(exc_value, TencentCloudSDKException):
388
error_data = {
389
'timestamp': datetime.utcnow().isoformat(),
390
'error_code': exc_value.get_code(),
391
'error_message': exc_value.get_message(),
392
'request_id': exc_value.get_request_id(),
393
'service': getattr(record, 'service', 'unknown'),
394
'region': getattr(record, 'region', 'unknown')
395
}
396
397
# Send to monitoring system (implement your own)
398
self.send_to_monitoring(error_data)
399
400
def send_to_monitoring(self, error_data):
401
"""Send error data to monitoring system."""
402
# Implement integration with your monitoring/alerting system
403
print(f"MONITOR: {json.dumps(error_data)}")
404
405
# Setup monitoring
406
monitor_handler = TencentCloudErrorHandler()
407
logger = logging.getLogger("tencentcloud.errors")
408
logger.addHandler(monitor_handler)
409
logger.setLevel(logging.ERROR)
410
411
# Use in error handling
412
try:
413
response = client.DescribeInstances(request)
414
except TencentCloudSDKException as err:
415
logger.error("API call failed", exc_info=True, extra={
416
'service': 'cvm',
417
'region': 'ap-shanghai'
418
})
419
raise
420
```