0
# Error Handling
1
2
Complete exception hierarchy for robust error handling, covering connection issues, protocol errors, and operational failures. pylibmc provides specific exception types to help applications handle different error conditions appropriately.
3
4
## Capabilities
5
6
### Base Exceptions
7
8
Foundation exception classes that form the hierarchy for all pylibmc errors.
9
10
```python { .api }
11
class Error(Exception):
12
"""
13
Base exception for all pylibmc errors.
14
All other pylibmc exceptions inherit from this class.
15
"""
16
17
class MemcachedError(Error):
18
"""
19
Backwards compatible alias for Error.
20
Maintained for compatibility with older versions.
21
"""
22
23
class CacheMiss(Error):
24
"""
25
Raised when a requested key is not found in the cache.
26
This is a normal condition, not necessarily an error.
27
"""
28
```
29
30
### Connection Errors
31
32
Exceptions related to network connectivity and server communication.
33
34
```python { .api }
35
class ConnectionError(Error):
36
"""
37
General connection failure to memcached server.
38
Raised when client cannot establish or maintain connection.
39
"""
40
41
class ConnectionBindError(Error):
42
"""
43
Failed to bind connection to specific address.
44
Usually indicates network configuration issues.
45
"""
46
47
class HostLookupError(Error):
48
"""
49
DNS resolution failed for memcached server hostname.
50
Check hostname spelling and DNS configuration.
51
"""
52
53
class SocketCreateError(Error):
54
"""
55
Failed to create network socket for connection.
56
May indicate system resource limits or permissions.
57
"""
58
59
class UnixSocketError(Error):
60
"""
61
Error specific to Unix domain socket connections.
62
Check socket file permissions and path.
63
"""
64
```
65
66
### Protocol Errors
67
68
Exceptions related to memcached protocol communication and data format issues.
69
70
```python { .api }
71
class ProtocolError(Error):
72
"""
73
Memcached protocol violation or unexpected response.
74
Usually indicates server or network issues.
75
"""
76
77
class WriteError(Error):
78
"""
79
Failed to write data to memcached server.
80
May indicate network issues or server problems.
81
"""
82
83
class ReadError(Error):
84
"""
85
Failed to read data from memcached server.
86
May indicate network timeout or connection issues.
87
"""
88
89
class UnknownReadFailure(Error):
90
"""
91
Unexpected failure during read operation.
92
Generic read error when specific cause is unknown.
93
"""
94
```
95
96
### Server-Side Errors
97
98
Exceptions originating from memcached server responses and conditions.
99
100
```python { .api }
101
class ServerError(Error):
102
"""
103
Internal server error reported by memcached.
104
Usually indicates server-side issues or bugs.
105
"""
106
107
class ClientError(Error):
108
"""
109
Client request error as reported by memcached server.
110
Indicates malformed request or invalid operation.
111
"""
112
113
class ServerDead(Error):
114
"""
115
Server is marked as dead due to repeated failures.
116
Server will be retried after retry_timeout period.
117
"""
118
119
class ServerDown(Error):
120
"""
121
Server is currently down or unreachable.
122
Temporary condition that may resolve automatically.
123
"""
124
125
class NoServers(Error):
126
"""
127
No servers are available for operations.
128
All servers may be down or configuration is empty.
129
"""
130
```
131
132
### Data-Related Errors
133
134
Exceptions related to data operations, key validation, and value constraints.
135
136
```python { .api }
137
class DataExists(Error):
138
"""
139
Data already exists when using add operation.
140
Normal condition when key already present for add().
141
"""
142
143
class DataDoesNotExist(Error):
144
"""
145
Data does not exist for replace or update operation.
146
Normal condition when key missing for replace().
147
"""
148
149
class NotFound(Error):
150
"""
151
Requested key was not found in cache.
152
Similar to CacheMiss but used in different contexts.
153
"""
154
155
class BadKeyProvided(Error):
156
"""
157
Invalid key format or characters provided.
158
Key may contain invalid characters or be too long.
159
"""
160
161
class TooBig(Error):
162
"""
163
Value exceeds maximum size limit for memcached.
164
Default limit is 1MB, configurable on server.
165
"""
166
```
167
168
### Operational Errors
169
170
Exceptions related to operation state and resource management.
171
172
```python { .api }
173
class Failure(Error):
174
"""
175
General operation failure without specific cause.
176
Generic error when operation cannot complete.
177
"""
178
179
class AllocationError(Error):
180
"""
181
Memory allocation failure within pylibmc or libmemcached.
182
May indicate system memory pressure.
183
"""
184
185
class SomeErrors(Error):
186
"""
187
Some operations in batch failed while others succeeded.
188
Used with multi-key operations for partial failures.
189
"""
190
191
class FetchNotFinished(Error):
192
"""
193
Attempt to access results before fetch operation completed.
194
Usually indicates improper async operation handling.
195
"""
196
197
class NotSupportedError(Error):
198
"""
199
Requested operation is not supported by server or configuration.
200
Feature may require specific server version or compile options.
201
"""
202
203
class InvalidHostProtocolError(Error):
204
"""
205
Invalid protocol specified in server host specification.
206
Check server URL format and protocol specification.
207
"""
208
209
class UnknownStatKey(Error):
210
"""
211
Requested statistics key is not recognized by server.
212
Use get_stats() without arguments to see available keys.
213
"""
214
```
215
216
### Exception Information
217
218
Access to complete exception catalog and metadata.
219
220
```python { .api }
221
errors: tuple # Tuple of all exception classes
222
exceptions: list # List of (name, exception_class) tuples
223
```
224
225
## Usage Examples
226
227
### Basic Error Handling
228
229
```python
230
import pylibmc
231
232
client = pylibmc.Client(["localhost:11211"])
233
234
try:
235
value = client.get("nonexistent_key")
236
if value is None:
237
print("Key not found")
238
except pylibmc.CacheMiss:
239
print("Cache miss - key doesn't exist")
240
except pylibmc.ConnectionError:
241
print("Cannot connect to memcached server")
242
except pylibmc.Error as e:
243
print(f"Memcached error: {e}")
244
```
245
246
### Comprehensive Error Handling
247
248
```python
249
import pylibmc
250
import logging
251
252
logger = logging.getLogger(__name__)
253
254
def safe_cache_get(client, key, default=None):
255
"""Safely get value from cache with comprehensive error handling."""
256
try:
257
return client.get(key)
258
259
except pylibmc.CacheMiss:
260
logger.debug(f"Cache miss for key: {key}")
261
return default
262
263
except pylibmc.ConnectionError as e:
264
logger.error(f"Connection failed: {e}")
265
return default
266
267
except pylibmc.ServerError as e:
268
logger.error(f"Server error: {e}")
269
return default
270
271
except pylibmc.BadKeyProvided as e:
272
logger.warning(f"Invalid key format: {key} - {e}")
273
return default
274
275
except pylibmc.Error as e:
276
logger.exception(f"Unexpected cache error: {e}")
277
return default
278
279
def safe_cache_set(client, key, value, time=0):
280
"""Safely set value in cache with error handling."""
281
try:
282
return client.set(key, value, time)
283
284
except pylibmc.TooBig as e:
285
logger.warning(f"Value too large for key {key}: {e}")
286
return False
287
288
except pylibmc.BadKeyProvided as e:
289
logger.warning(f"Invalid key format: {key} - {e}")
290
return False
291
292
except pylibmc.ConnectionError as e:
293
logger.error(f"Connection failed during set: {e}")
294
return False
295
296
except pylibmc.ServerError as e:
297
logger.error(f"Server error during set: {e}")
298
return False
299
300
except pylibmc.Error as e:
301
logger.exception(f"Unexpected error during set: {e}")
302
return False
303
```
304
305
### Batch Operation Error Handling
306
307
```python
308
import pylibmc
309
310
client = pylibmc.Client(["localhost:11211"])
311
312
def safe_multi_get(client, keys):
313
"""Get multiple keys with proper error handling."""
314
try:
315
return client.get_multi(keys)
316
317
except pylibmc.SomeErrors as e:
318
logger.warning(f"Some keys failed in multi-get: {e}")
319
# Partial results may still be available
320
return {}
321
322
except pylibmc.NoServers as e:
323
logger.error(f"No servers available: {e}")
324
return {}
325
326
except pylibmc.Error as e:
327
logger.exception(f"Multi-get failed: {e}")
328
return {}
329
330
def safe_multi_set(client, key_value_pairs):
331
"""Set multiple keys with error handling."""
332
try:
333
failed_keys = client.set_multi(key_value_pairs)
334
if failed_keys:
335
logger.warning(f"Failed to set keys: {failed_keys}")
336
return failed_keys
337
338
except pylibmc.SomeErrors as e:
339
logger.warning(f"Partial failure in multi-set: {e}")
340
return list(key_value_pairs.keys()) # Assume all failed
341
342
except pylibmc.Error as e:
343
logger.exception(f"Multi-set failed completely: {e}")
344
return list(key_value_pairs.keys())
345
```
346
347
### Connection Pool Error Handling
348
349
```python
350
import pylibmc
351
from queue import Empty
352
353
client = pylibmc.Client(["localhost:11211"])
354
pool = pylibmc.ClientPool()
355
pool.fill(client, 5)
356
357
def safe_pooled_operation(key, value=None):
358
"""Perform cache operation using pool with error handling."""
359
try:
360
with pool.reserve(block=False) as pooled_client:
361
if value is not None:
362
return pooled_client.set(key, value)
363
else:
364
return pooled_client.get(key)
365
366
except Empty:
367
logger.warning("Connection pool exhausted")
368
return None
369
370
except pylibmc.ConnectionError as e:
371
logger.error(f"Connection error in pool: {e}")
372
return None
373
374
except pylibmc.Error as e:
375
logger.exception(f"Cache error in pool: {e}")
376
return None
377
```
378
379
### Server Failure Recovery
380
381
```python
382
import pylibmc
383
import time
384
385
def create_resilient_client():
386
"""Create client configured for automatic failure recovery."""
387
client = pylibmc.Client([
388
"server1:11211",
389
"server2:11211",
390
"server3:11211"
391
], binary=True)
392
393
# Configure for automatic failover
394
client.behaviors = {
395
"auto_eject": True, # Remove failed servers
396
"failure_limit": 2, # Failures before ejection
397
"retry_timeout": 30, # Retry failed servers after 30s
398
"connect_timeout": 2000, # Quick connection timeout
399
}
400
401
return client
402
403
def resilient_operation(client, operation_func, max_retries=3):
404
"""Perform operation with retry logic for server failures."""
405
for attempt in range(max_retries):
406
try:
407
return operation_func()
408
409
except (pylibmc.ServerDead, pylibmc.ServerDown, pylibmc.NoServers) as e:
410
if attempt == max_retries - 1:
411
logger.error(f"All retry attempts failed: {e}")
412
raise
413
414
logger.warning(f"Server failure (attempt {attempt + 1}): {e}")
415
time.sleep(2 ** attempt) # Exponential backoff
416
417
except pylibmc.ConnectionError as e:
418
if attempt == max_retries - 1:
419
logger.error(f"Connection failed after retries: {e}")
420
raise
421
422
logger.warning(f"Connection error (attempt {attempt + 1}): {e}")
423
time.sleep(1)
424
425
# Usage
426
client = create_resilient_client()
427
428
def get_user_data(user_id):
429
return client.get(f"user:{user_id}")
430
431
try:
432
user_data = resilient_operation(client, lambda: get_user_data(123))
433
except pylibmc.Error:
434
# Fallback to database or default value
435
user_data = None
436
```
437
438
### Error Pattern Analysis
439
440
```python
441
import pylibmc
442
from collections import defaultdict, Counter
443
444
class CacheErrorTracker:
445
"""Track and analyze cache error patterns."""
446
447
def __init__(self):
448
self.error_counts = Counter()
449
self.error_details = defaultdict(list)
450
451
def record_error(self, operation, error):
452
"""Record an error for analysis."""
453
error_type = type(error).__name__
454
self.error_counts[error_type] += 1
455
self.error_details[error_type].append({
456
'operation': operation,
457
'message': str(error),
458
'timestamp': time.time()
459
})
460
461
def get_stats(self):
462
"""Get error statistics."""
463
return dict(self.error_counts)
464
465
def should_fallback(self, error_threshold=10):
466
"""Determine if error rate suggests fallback needed."""
467
connection_errors = (
468
self.error_counts.get('ConnectionError', 0) +
469
self.error_counts.get('ServerDead', 0) +
470
self.error_counts.get('NoServers', 0)
471
)
472
return connection_errors >= error_threshold
473
474
# Usage
475
tracker = CacheErrorTracker()
476
client = pylibmc.Client(["localhost:11211"])
477
478
def monitored_cache_get(key):
479
"""Cache get with error monitoring."""
480
try:
481
return client.get(key)
482
except pylibmc.Error as e:
483
tracker.record_error('get', e)
484
485
if tracker.should_fallback():
486
logger.warning("High error rate - consider fallback strategy")
487
488
raise
489
```