0
# Error Handling and Exceptions
1
2
Complete exception hierarchy mirroring PyMongo's error system with support for operation failures, write errors, and configuration errors. Proper error handling ensures robust application behavior.
3
4
## Capabilities
5
6
### Base Exception Classes
7
8
Foundation exception classes that form the hierarchy for all MongoDB-related errors.
9
10
```python { .api }
11
class PyMongoError(Exception):
12
"""
13
Base exception class for all MongoDB-related errors.
14
15
All mongomock exceptions inherit from this base class,
16
providing consistent error handling patterns.
17
"""
18
19
class OperationFailure(PyMongoError):
20
"""
21
Raised when a database operation fails.
22
23
Common base class for database operation errors including
24
write failures, query errors, and command execution problems.
25
"""
26
27
def __init__(self, message, code=None, details=None):
28
"""
29
Parameters:
30
- message: str, error message
31
- code: int, MongoDB error code
32
- details: dict, additional error details
33
"""
34
35
@property
36
def code(self):
37
"""int: MongoDB error code"""
38
39
@property
40
def details(self):
41
"""dict: additional error details"""
42
43
class ConfigurationError(PyMongoError):
44
"""
45
Raised for client configuration errors.
46
47
Indicates problems with connection strings, client options,
48
or other configuration-related issues.
49
"""
50
```
51
52
**Usage Example:**
53
54
```python
55
import mongomock
56
57
try:
58
collection = mongomock.MongoClient().db.collection
59
collection.insert_one({'_id': 1, 'data': 'test'})
60
collection.insert_one({'_id': 1, 'data': 'duplicate'}) # Will raise error
61
except mongomock.PyMongoError as e:
62
print(f"MongoDB error: {e}")
63
except mongomock.OperationFailure as e:
64
print(f"Operation failed: {e}, Code: {e.code}")
65
```
66
67
### Write Operation Errors
68
69
Specific exceptions for write operation failures including constraint violations and bulk operation errors.
70
71
```python { .api }
72
class WriteError(OperationFailure):
73
"""
74
Raised when a write operation fails.
75
76
Base class for write-specific errors including constraint
77
violations, validation failures, and write conflicts.
78
"""
79
80
class DuplicateKeyError(WriteError):
81
"""
82
Raised when a write operation violates a unique constraint.
83
84
Occurs when attempting to insert or update documents with
85
duplicate values for fields with unique indexes.
86
"""
87
88
class BulkWriteError(OperationFailure):
89
"""
90
Raised when a bulk write operation fails.
91
92
Contains details about which operations succeeded and
93
which failed during bulk write execution.
94
"""
95
96
def __init__(self, results):
97
"""
98
Parameters:
99
- results: dict, bulk operation results with error details
100
"""
101
```
102
103
**Usage Example:**
104
105
```python
106
import mongomock
107
108
collection = mongomock.MongoClient().db.users
109
110
# Create unique index
111
collection.create_index('email', unique=True)
112
113
try:
114
# First insert succeeds
115
collection.insert_one({'email': 'user@example.com', 'name': 'Alice'})
116
117
# Second insert with same email fails
118
collection.insert_one({'email': 'user@example.com', 'name': 'Bob'})
119
120
except mongomock.DuplicateKeyError as e:
121
print(f"Duplicate key error: {e}")
122
print(f"Error code: {e.code}")
123
124
# Bulk write error handling
125
try:
126
bulk_ops = [
127
{'insertOne': {'document': {'email': 'new@example.com'}}},
128
{'insertOne': {'document': {'email': 'user@example.com'}}}, # Duplicate
129
{'insertOne': {'document': {'email': 'another@example.com'}}}
130
]
131
collection.bulk_write(bulk_ops)
132
133
except mongomock.BulkWriteError as e:
134
print(f"Bulk write failed: {e}")
135
print(f"Error details: {e.details}")
136
```
137
138
### Collection and Database Errors
139
140
Exceptions related to collection and database operations including invalid names and operations.
141
142
```python { .api }
143
class CollectionInvalid(PyMongoError):
144
"""
145
Raised when attempting invalid operations on collections.
146
147
Examples include creating collections with invalid options
148
or performing operations on non-existent collections.
149
"""
150
151
class InvalidName(PyMongoError):
152
"""
153
Raised when database or collection names are invalid.
154
155
MongoDB has specific naming restrictions for databases
156
and collections that must be followed.
157
"""
158
159
class InvalidOperation(PyMongoError):
160
"""
161
Raised when attempting invalid operations.
162
163
Covers various invalid operation scenarios including
164
inappropriate method calls or invalid parameter combinations.
165
"""
166
```
167
168
**Usage Example:**
169
170
```python
171
import mongomock
172
173
client = mongomock.MongoClient()
174
175
try:
176
# Invalid database name
177
db = client['invalid/name']
178
db.collection.insert_one({'test': 'data'})
179
180
except mongomock.InvalidName as e:
181
print(f"Invalid name: {e}")
182
183
try:
184
# Invalid collection operation
185
db = client.testdb
186
db.create_collection('existing_collection')
187
db.create_collection('existing_collection') # May raise CollectionInvalid
188
189
except mongomock.CollectionInvalid as e:
190
print(f"Collection invalid: {e}")
191
192
try:
193
# Invalid operation example
194
collection = db.collection
195
collection.find_one_and_update({}, {}) # Invalid empty update
196
197
except mongomock.InvalidOperation as e:
198
print(f"Invalid operation: {e}")
199
```
200
201
### URI and Configuration Errors
202
203
Exceptions for connection string parsing and configuration problems.
204
205
```python { .api }
206
class InvalidURI(ConfigurationError):
207
"""
208
Raised when MongoDB connection URI is malformed.
209
210
Occurs when connection strings don't follow MongoDB URI
211
format specifications or contain invalid parameters.
212
"""
213
```
214
215
**Usage Example:**
216
217
```python
218
import mongomock
219
220
try:
221
# Invalid URI format
222
client = mongomock.MongoClient('invalid://bad-uri-format')
223
224
except mongomock.InvalidURI as e:
225
print(f"Invalid URI: {e}")
226
227
try:
228
# Configuration error
229
client = mongomock.MongoClient(invalid_option='bad_value')
230
231
except mongomock.ConfigurationError as e:
232
print(f"Configuration error: {e}")
233
```
234
235
### Error Handling Patterns
236
237
Best practices for handling mongomock exceptions in applications.
238
239
**Specific Exception Handling:**
240
241
```python
242
import mongomock
243
244
def safe_insert_user(collection, user_data):
245
"""Safely insert user with proper error handling."""
246
try:
247
result = collection.insert_one(user_data)
248
return result.inserted_id
249
250
except mongomock.DuplicateKeyError:
251
print("User already exists with this email")
252
return None
253
254
except mongomock.WriteError as e:
255
print(f"Write operation failed: {e}")
256
return None
257
258
except mongomock.OperationFailure as e:
259
print(f"Database operation failed: {e.code} - {e}")
260
return None
261
262
# Usage
263
collection = mongomock.MongoClient().db.users
264
collection.create_index('email', unique=True)
265
266
user_id = safe_insert_user(collection, {
267
'email': 'user@example.com',
268
'name': 'Alice'
269
})
270
```
271
272
**Bulk Operation Error Handling:**
273
274
```python
275
def safe_bulk_insert(collection, documents):
276
"""Handle bulk insert with error recovery."""
277
try:
278
result = collection.insert_many(documents, ordered=False)
279
return result.inserted_ids
280
281
except mongomock.BulkWriteError as e:
282
print(f"Bulk operation partially failed: {e}")
283
284
# Access bulk write result details
285
if hasattr(e, 'details'):
286
write_errors = e.details.get('writeErrors', [])
287
for error in write_errors:
288
print(f"Error at index {error['index']}: {error['errmsg']}")
289
290
# Return successful insertions
291
return getattr(e, 'inserted_ids', [])
292
293
except mongomock.OperationFailure as e:
294
print(f"Bulk operation completely failed: {e}")
295
return []
296
297
# Usage with error recovery
298
documents = [
299
{'email': 'user1@example.com', 'name': 'User 1'},
300
{'email': 'user2@example.com', 'name': 'User 2'},
301
{'email': 'user1@example.com', 'name': 'Duplicate'}, # Will fail
302
{'email': 'user3@example.com', 'name': 'User 3'}
303
]
304
305
inserted_ids = safe_bulk_insert(collection, documents)
306
print(f"Successfully inserted {len(inserted_ids)} documents")
307
```
308
309
**Generic Error Handling:**
310
311
```python
312
def robust_query(collection, query_filter):
313
"""Perform query with comprehensive error handling."""
314
try:
315
return list(collection.find(query_filter))
316
317
except mongomock.OperationFailure as e:
318
print(f"Query failed: {e}")
319
320
# Check specific error codes
321
if e.code == 2: # BadValue
322
print("Invalid query parameters")
323
elif e.code == 11000: # DuplicateKey
324
print("Duplicate key error during query")
325
else:
326
print(f"Unknown operation failure: {e.code}")
327
328
return []
329
330
except mongomock.PyMongoError as e:
331
print(f"General MongoDB error: {e}")
332
return []
333
334
except Exception as e:
335
print(f"Unexpected error: {e}")
336
return []
337
```
338
339
### Error Code Constants
340
341
Common MongoDB error codes that may be encountered.
342
343
```python { .api }
344
# Common MongoDB error codes
345
ERROR_CODES = {
346
2: 'BadValue', # Invalid parameter value
347
11000: 'DuplicateKey', # Duplicate key error
348
11001: 'DuplicateKey', # Duplicate key on update
349
12582: 'DuplicateKey', # Duplicate key in capped collection
350
16550: 'CommandNotFound', # Unknown command
351
26: 'NamespaceNotFound', # Collection/database not found
352
50: 'MaxTimeMSExpired', # Operation exceeded time limit
353
96: 'OperationFailed', # Generic operation failure
354
}
355
```
356
357
**Usage Example:**
358
359
```python
360
import mongomock
361
362
def handle_error_by_code(error):
363
"""Handle errors based on MongoDB error codes."""
364
if hasattr(error, 'code'):
365
if error.code == 11000:
366
return "Duplicate key - record already exists"
367
elif error.code == 2:
368
return "Invalid parameter value provided"
369
elif error.code == 26:
370
return "Collection or database not found"
371
else:
372
return f"MongoDB error {error.code}: {error}"
373
return str(error)
374
375
# Example usage
376
try:
377
collection = mongomock.MongoClient().db.test
378
collection.create_index('email', unique=True)
379
collection.insert_one({'email': 'test@example.com'})
380
collection.insert_one({'email': 'test@example.com'}) # Duplicate
381
382
except mongomock.PyMongoError as e:
383
error_message = handle_error_by_code(e)
384
print(f"Handled error: {error_message}")
385
```
386
387
### Testing Error Conditions
388
389
Patterns for testing error handling in applications using mongomock.
390
391
```python
392
import unittest
393
import mongomock
394
395
class TestErrorHandling(unittest.TestCase):
396
def setUp(self):
397
self.client = mongomock.MongoClient()
398
self.collection = self.client.db.test
399
self.collection.create_index('email', unique=True)
400
401
def test_duplicate_key_error(self):
402
"""Test handling of duplicate key errors."""
403
self.collection.insert_one({'email': 'test@example.com'})
404
405
with self.assertRaises(mongomock.DuplicateKeyError):
406
self.collection.insert_one({'email': 'test@example.com'})
407
408
def test_invalid_operation_error(self):
409
"""Test handling of invalid operations."""
410
with self.assertRaises(mongomock.InvalidOperation):
411
self.collection.update_one({}, {}) # Empty update
412
413
def test_collection_invalid_error(self):
414
"""Test collection validation errors."""
415
with self.assertRaises(mongomock.CollectionInvalid):
416
self.client.db.create_collection('invalid..name')
417
418
def test_error_recovery(self):
419
"""Test error recovery patterns."""
420
try:
421
self.collection.insert_one({'email': 'test@example.com'})
422
self.collection.insert_one({'email': 'test@example.com'})
423
except mongomock.DuplicateKeyError:
424
# Recover by updating instead
425
result = self.collection.update_one(
426
{'email': 'test@example.com'},
427
{'$set': {'updated': True}}
428
)
429
self.assertEqual(result.modified_count, 1)
430
```