0
# Error Handling & Types
1
2
Comprehensive exception hierarchy and type definitions for structured error handling and type safety in python-arango operations. Includes operation-specific exceptions, error codes, and result wrappers.
3
4
## Capabilities
5
6
### Exception Hierarchy
7
8
Complete exception classes for all ArangoDB operations with inheritance from base exception types.
9
10
```python { .api }
11
class ArangoError(Exception):
12
"""Base exception for all ArangoDB errors."""
13
14
@property
15
def error_code(self) -> int:
16
"""ArangoDB error code."""
17
18
@property
19
def error_message(self) -> str:
20
"""Error message."""
21
22
@property
23
def http_code(self) -> int:
24
"""HTTP status code."""
25
26
class ArangoServerError(ArangoError):
27
"""Server-side errors from ArangoDB."""
28
29
class ArangoClientError(ArangoError):
30
"""Client-side errors in python-arango."""
31
32
class AsyncExecuteError(ArangoError):
33
"""Errors in async job execution."""
34
```
35
36
### Database Operation Exceptions
37
38
Specific exceptions for database lifecycle and management operations.
39
40
```python { .api }
41
# Database operations
42
class DatabaseListError(ArangoServerError):
43
"""Error listing databases."""
44
45
class DatabaseCreateError(ArangoServerError):
46
"""Error creating database."""
47
48
class DatabaseDeleteError(ArangoServerError):
49
"""Error deleting database."""
50
51
class DatabasePropertiesError(ArangoServerError):
52
"""Error getting database properties."""
53
```
54
55
### Collection Operation Exceptions
56
57
Exceptions for collection management and document operations.
58
59
```python { .api }
60
# Collection management
61
class CollectionListError(ArangoServerError):
62
"""Error listing collections."""
63
64
class CollectionCreateError(ArangoServerError):
65
"""Error creating collection."""
66
67
class CollectionDeleteError(ArangoServerError):
68
"""Error deleting collection."""
69
70
class CollectionPropertiesError(ArangoServerError):
71
"""Error getting collection properties."""
72
73
class CollectionConfigureError(ArangoServerError):
74
"""Error configuring collection."""
75
76
class CollectionStatisticsError(ArangoServerError):
77
"""Error getting collection statistics."""
78
79
class CollectionRevisionError(ArangoServerError):
80
"""Error getting collection revision."""
81
82
class CollectionChecksumError(ArangoServerError):
83
"""Error calculating collection checksum."""
84
85
# Document operations
86
class DocumentInsertError(ArangoServerError):
87
"""Error inserting document."""
88
89
class DocumentGetError(ArangoServerError):
90
"""Error getting document."""
91
92
class DocumentUpdateError(ArangoServerError):
93
"""Error updating document."""
94
95
class DocumentReplaceError(ArangoServerError):
96
"""Error replacing document."""
97
98
class DocumentDeleteError(ArangoServerError):
99
"""Error deleting document."""
100
101
class DocumentRevisionError(ArangoServerError):
102
"""Document revision conflict."""
103
104
class DocumentParseError(ArangoClientError):
105
"""Error parsing document."""
106
```
107
108
### AQL Query Exceptions
109
110
Exceptions for AQL query operations, analysis, and management.
111
112
```python { .api }
113
# Query execution
114
class AQLQueryExecuteError(ArangoServerError):
115
"""Error executing AQL query."""
116
117
class AQLQueryExplainError(ArangoServerError):
118
"""Error explaining AQL query."""
119
120
class AQLQueryValidateError(ArangoServerError):
121
"""Error validating AQL query."""
122
123
class AQLQueryListError(ArangoServerError):
124
"""Error listing running queries."""
125
126
class AQLQueryKillError(ArangoServerError):
127
"""Error killing AQL query."""
128
129
class AQLQueryCachePropertiesError(ArangoServerError):
130
"""Error getting query cache properties."""
131
132
class AQLQueryCacheConfigureError(ArangoServerError):
133
"""Error configuring query cache."""
134
135
class AQLQueryCacheClearError(ArangoServerError):
136
"""Error clearing query cache."""
137
138
# User-defined functions
139
class AQLFunctionListError(ArangoServerError):
140
"""Error listing AQL functions."""
141
142
class AQLFunctionCreateError(ArangoServerError):
143
"""Error creating AQL function."""
144
145
class AQLFunctionDeleteError(ArangoServerError):
146
"""Error deleting AQL function."""
147
```
148
149
### Graph Operation Exceptions
150
151
Exceptions for graph management, vertex, and edge operations.
152
153
```python { .api }
154
# Graph management
155
class GraphListError(ArangoServerError):
156
"""Error listing graphs."""
157
158
class GraphCreateError(ArangoServerError):
159
"""Error creating graph."""
160
161
class GraphDeleteError(ArangoServerError):
162
"""Error deleting graph."""
163
164
class GraphPropertiesError(ArangoServerError):
165
"""Error getting graph properties."""
166
167
# Vertex operations
168
class VertexCollectionListError(ArangoServerError):
169
"""Error listing vertex collections."""
170
171
class VertexCollectionCreateError(ArangoServerError):
172
"""Error creating vertex collection."""
173
174
class VertexCollectionDeleteError(ArangoServerError):
175
"""Error deleting vertex collection."""
176
177
class VertexGetError(ArangoServerError):
178
"""Error getting vertex."""
179
180
class VertexInsertError(ArangoServerError):
181
"""Error inserting vertex."""
182
183
class VertexUpdateError(ArangoServerError):
184
"""Error updating vertex."""
185
186
class VertexReplaceError(ArangoServerError):
187
"""Error replacing vertex."""
188
189
class VertexDeleteError(ArangoServerError):
190
"""Error deleting vertex."""
191
192
# Edge operations
193
class EdgeDefinitionListError(ArangoServerError):
194
"""Error listing edge definitions."""
195
196
class EdgeDefinitionCreateError(ArangoServerError):
197
"""Error creating edge definition."""
198
199
class EdgeDefinitionReplaceError(ArangoServerError):
200
"""Error replacing edge definition."""
201
202
class EdgeDefinitionDeleteError(ArangoServerError):
203
"""Error deleting edge definition."""
204
205
class EdgeGetError(ArangoServerError):
206
"""Error getting edge."""
207
208
class EdgeInsertError(ArangoServerError):
209
"""Error inserting edge."""
210
211
class EdgeUpdateError(ArangoServerError):
212
"""Error updating edge."""
213
214
class EdgeReplaceError(ArangoServerError):
215
"""Error replacing edge."""
216
217
class EdgeDeleteError(ArangoServerError):
218
"""Error deleting edge."""
219
220
class EdgeListError(ArangoServerError):
221
"""Error listing edges."""
222
223
class GraphTraverseError(ArangoServerError):
224
"""Error in graph traversal."""
225
```
226
227
### Index Operation Exceptions
228
229
Exceptions for index management and operations.
230
231
```python { .api }
232
class IndexListError(ArangoServerError):
233
"""Error listing indexes."""
234
235
class IndexCreateError(ArangoServerError):
236
"""Error creating index."""
237
238
class IndexDeleteError(ArangoServerError):
239
"""Error deleting index."""
240
```
241
242
### Transaction Exceptions
243
244
Exceptions for transaction operations and management.
245
246
```python { .api }
247
class TransactionInitError(ArangoServerError):
248
"""Error initializing transaction."""
249
250
class TransactionStatusError(ArangoServerError):
251
"""Error getting transaction status."""
252
253
class TransactionExecuteError(ArangoServerError):
254
"""Error executing transaction."""
255
256
class TransactionCommitError(ArangoServerError):
257
"""Error committing transaction."""
258
259
class TransactionAbortError(ArangoServerError):
260
"""Error aborting transaction."""
261
```
262
263
### User Management Exceptions
264
265
Exceptions for user account operations.
266
267
```python { .api }
268
class UserListError(ArangoServerError):
269
"""Error listing users."""
270
271
class UserGetError(ArangoServerError):
272
"""Error getting user."""
273
274
class UserCreateError(ArangoServerError):
275
"""Error creating user."""
276
277
class UserUpdateError(ArangoServerError):
278
"""Error updating user."""
279
280
class UserReplaceError(ArangoServerError):
281
"""Error replacing user."""
282
283
class UserDeleteError(ArangoServerError):
284
"""Error deleting user."""
285
286
class PermissionListError(ArangoServerError):
287
"""Error listing permissions."""
288
289
class PermissionGetError(ArangoServerError):
290
"""Error getting permission."""
291
292
class PermissionUpdateError(ArangoServerError):
293
"""Error updating permission."""
294
295
class PermissionResetError(ArangoServerError):
296
"""Error resetting permission."""
297
```
298
299
### Error Code Constants
300
301
Comprehensive error code constants from ArangoDB server.
302
303
```python { .api }
304
# General errors
305
ERROR_NO_ERROR = 0
306
ERROR_FAILED = 1
307
ERROR_SYS_ERROR = 2
308
ERROR_OUT_OF_MEMORY = 3
309
ERROR_INTERNAL = 4
310
ERROR_ILLEGAL_NUMBER = 5
311
ERROR_NUMERIC_OVERFLOW = 6
312
ERROR_ILLEGAL_OPTION = 7
313
ERROR_DEAD_PID = 8
314
ERROR_NOT_IMPLEMENTED = 9
315
ERROR_BAD_PARAMETER = 10
316
ERROR_FORBIDDEN = 11
317
ERROR_OUT_OF_MEMORY_MMAP = 12
318
ERROR_CORRUPTED_CSV = 13
319
ERROR_FILE_NOT_FOUND = 14
320
ERROR_CANNOT_WRITE_FILE = 15
321
ERROR_CANNOT_OVERWRITE_FILE = 16
322
ERROR_TYPE_ERROR = 17
323
ERROR_LOCK_TIMEOUT = 18
324
ERROR_CANNOT_CREATE_DIRECTORY = 19
325
ERROR_CANNOT_CREATE_TEMP_FILE = 20
326
ERROR_REQUEST_CANCELED = 21
327
ERROR_DEBUG = 22
328
329
# HTTP errors
330
ERROR_HTTP_BAD_PARAMETER = 400
331
ERROR_HTTP_UNAUTHORIZED = 401
332
ERROR_HTTP_FORBIDDEN = 403
333
ERROR_HTTP_NOT_FOUND = 404
334
ERROR_HTTP_METHOD_NOT_ALLOWED = 405
335
ERROR_HTTP_NOT_ACCEPTABLE = 406
336
ERROR_HTTP_REQUEST_TIMEOUT = 408
337
ERROR_HTTP_CONFLICT = 409
338
ERROR_HTTP_GONE = 410
339
ERROR_HTTP_PRECONDITION_FAILED = 412
340
ERROR_HTTP_REQUEST_ENTITY_TOO_LARGE = 413
341
ERROR_HTTP_REQUEST_URI_TOO_LONG = 414
342
ERROR_HTTP_UNPROCESSABLE_ENTITY = 422
343
ERROR_HTTP_TOO_MANY_REQUESTS = 429
344
ERROR_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
345
ERROR_HTTP_INTERNAL_SERVER_ERROR = 500
346
ERROR_HTTP_NOT_IMPLEMENTED = 501
347
ERROR_HTTP_BAD_GATEWAY = 502
348
ERROR_HTTP_SERVICE_UNAVAILABLE = 503
349
ERROR_HTTP_GATEWAY_TIMEOUT = 504
350
351
# ArangoDB specific errors
352
ERROR_ARANGO_ILLEGAL_STATE = 1000
353
ERROR_ARANGO_DATAFILE_SEALED = 1002
354
ERROR_ARANGO_READ_ONLY = 1004
355
ERROR_ARANGO_DUPLICATE_IDENTIFIER = 1005
356
ERROR_ARANGO_DATAFILE_UNREADABLE = 1006
357
ERROR_ARANGO_DATAFILE_EMPTY = 1007
358
ERROR_ARANGO_RECOVERY = 1008
359
ERROR_ARANGO_DATAFILE_STATISTICS_NOT_FOUND = 1009
360
361
# Document errors
362
ERROR_ARANGO_CONFLICT = 1200
363
ERROR_ARANGO_DATADIR_NOT_WRITABLE = 1201
364
ERROR_ARANGO_DOCUMENT_NOT_FOUND = 1202
365
ERROR_ARANGO_DATA_SOURCE_NOT_FOUND = 1203
366
ERROR_ARANGO_COLLECTION_PARAMETER_MISSING = 1204
367
ERROR_ARANGO_DOCUMENT_HANDLE_BAD = 1205
368
ERROR_ARANGO_MAXIMAL_SIZE_TOO_SMALL = 1206
369
ERROR_ARANGO_DUPLICATE_NAME = 1207
370
ERROR_ARANGO_ILLEGAL_NAME = 1208
371
ERROR_ARANGO_NO_SUITABLE_INDEX = 1209
372
ERROR_ARANGO_CROSS_COLLECTION_REQUEST = 1210
373
ERROR_ARANGO_INDEX_NOT_FOUND = 1212
374
ERROR_ARANGO_CROSS_COLLECTION_TRANSACTION = 1213
375
ERROR_ARANGO_INDEX_HANDLE_BAD = 1214
376
ERROR_ARANGO_DOCUMENT_TOO_LARGE = 1216
377
ERROR_ARANGO_COLLECTION_NOT_UNLOADED = 1217
378
ERROR_ARANGO_COLLECTION_TYPE_INVALID = 1218
379
ERROR_ARANGO_VALIDATION_FAILED = 1219
380
ERROR_ARANGO_ATTRIBUTE_PARSER_FAILED = 1220
381
ERROR_ARANGO_DOCUMENT_KEY_BAD = 1221
382
ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED = 1222
383
ERROR_ARANGO_DATADIR_INVALID = 1224
384
ERROR_ARANGO_DOCUMENT_KEY_MISSING = 1225
385
ERROR_ARANGO_DOCUMENT_TYPE_INVALID = 1226
386
ERROR_ARANGO_DATABASE_NOT_FOUND = 1228
387
ERROR_ARANGO_DATABASE_NAME_INVALID = 1229
388
ERROR_ARANGO_USE_SYSTEM_DATABASE = 1230
389
ERROR_ARANGO_ENDPOINT_NOT_FOUND = 1231
390
ERROR_ARANGO_INVALID_KEY_GENERATOR = 1232
391
ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE = 1233
392
ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING = 1234
393
ERROR_ARANGO_INDEX_CREATION_FAILED = 1235
394
ERROR_ARANGO_WRITE_THROTTLE_TIMEOUT = 1236
395
396
# Query errors
397
ERROR_QUERY_KILLED = 1500
398
ERROR_QUERY_PARSE = 1501
399
ERROR_QUERY_EMPTY = 1502
400
ERROR_QUERY_SCRIPT = 1503
401
ERROR_QUERY_NUMBER_OUT_OF_RANGE = 1504
402
ERROR_QUERY_VARIABLE_NAME_INVALID = 1510
403
ERROR_QUERY_VARIABLE_REDECLARED = 1511
404
ERROR_QUERY_VARIABLE_NAME_UNKNOWN = 1512
405
ERROR_QUERY_COLLECTION_LOCK_FAILED = 1521
406
ERROR_QUERY_TOO_MANY_COLLECTIONS = 1522
407
ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED = 1530
408
ERROR_QUERY_FUNCTION_NAME_UNKNOWN = 1540
409
ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH = 1541
410
ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH = 1542
411
ERROR_QUERY_INVALID_REGEX = 1543
412
ERROR_QUERY_BIND_PARAMETERS_INVALID = 1550
413
ERROR_QUERY_BIND_PARAMETER_MISSING = 1551
414
ERROR_QUERY_BIND_PARAMETER_UNDECLARED = 1552
415
ERROR_QUERY_BIND_PARAMETER_TYPE = 1553
416
ERROR_QUERY_INVALID_LOGICAL_VALUE = 1560
417
ERROR_QUERY_INVALID_ARITHMETIC_VALUE = 1561
418
ERROR_QUERY_DIVISION_BY_ZERO = 1562
419
ERROR_QUERY_ARRAY_EXPECTED = 1563
420
ERROR_QUERY_FAIL_CALLED = 1569
421
ERROR_QUERY_GEO_INDEX_MISSING = 1570
422
ERROR_QUERY_FULLTEXT_INDEX_MISSING = 1571
423
ERROR_QUERY_INVALID_DATE_VALUE = 1572
424
ERROR_QUERY_MULTI_MODIFY = 1573
425
ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION = 1574
426
ERROR_QUERY_COMPILE_TIME_OPTIONS = 1575
427
ERROR_QUERY_EXCEPTION_OPTIONS = 1576
428
ERROR_QUERY_COLLECTION_USED_IN_EXPRESSION = 1577
429
ERROR_QUERY_DISALLOWED_DYNAMIC_CALL = 1578
430
ERROR_QUERY_ACCESS_AFTER_MODIFICATION = 1579
431
ERROR_QUERY_FUNCTION_INVALID_NAME = 1580
432
ERROR_QUERY_FUNCTION_INVALID_CODE = 1581
433
ERROR_QUERY_FUNCTION_NOT_FOUND = 1582
434
ERROR_QUERY_FUNCTION_RUNTIME_ERROR = 1583
435
436
# Transaction errors
437
ERROR_TRANSACTION_INTERNAL = 1650
438
ERROR_TRANSACTION_NESTED = 1651
439
ERROR_TRANSACTION_UNREGISTERED_COLLECTION = 1652
440
ERROR_TRANSACTION_DISALLOWED_OPERATION = 1653
441
ERROR_TRANSACTION_ABORTED = 1654
442
ERROR_TRANSACTION_NOT_FOUND = 1655
443
```
444
445
### Type Definitions
446
447
Common type aliases and interfaces used throughout the API.
448
449
```python { .api }
450
# Type aliases
451
Json = Dict[str, Any]
452
"""Dictionary representing JSON object."""
453
454
Jsons = List[Json]
455
"""List of JSON objects."""
456
457
Result = Union[T, ArangoError]
458
"""Result wrapper that contains either success value or error."""
459
460
Headers = Optional[MutableMapping[str, str]]
461
"""HTTP headers mapping."""
462
463
DataTypes = Union[str, int, float, bool, None, Dict, List]
464
"""Supported data types for bind variables."""
465
466
Number = Union[int, float]
467
"""Numeric types."""
468
469
# Request/Response types
470
class Request:
471
"""HTTP request wrapper."""
472
473
@property
474
def method(self) -> str:
475
"""HTTP method."""
476
477
@property
478
def endpoint(self) -> str:
479
"""Request endpoint."""
480
481
@property
482
def headers(self) -> Headers:
483
"""Request headers."""
484
485
@property
486
def params(self) -> Optional[Dict[str, str]]:
487
"""Query parameters."""
488
489
@property
490
def data(self) -> Any:
491
"""Request body data."""
492
493
class Response:
494
"""HTTP response wrapper."""
495
496
@property
497
def method(self) -> str:
498
"""HTTP method."""
499
500
@property
501
def url(self) -> str:
502
"""Request URL."""
503
504
@property
505
def headers(self) -> Headers:
506
"""Response headers."""
507
508
@property
509
def status_code(self) -> int:
510
"""HTTP status code."""
511
512
@property
513
def status_text(self) -> str:
514
"""HTTP status text."""
515
516
@property
517
def raw_body(self) -> str:
518
"""Raw response body."""
519
520
@property
521
def body(self) -> Any:
522
"""Parsed response body."""
523
524
@property
525
def error_code(self) -> Optional[int]:
526
"""ArangoDB error code."""
527
528
@property
529
def error_message(self) -> Optional[str]:
530
"""Error message."""
531
532
@property
533
def is_success(self) -> bool:
534
"""True if request was successful."""
535
536
class Result:
537
"""Result wrapper for API operations."""
538
539
def __init__(self, value: Any = None, error: Optional[ArangoError] = None):
540
"""Initialize result."""
541
542
@property
543
def value(self) -> Any:
544
"""Result value."""
545
546
@property
547
def error(self) -> Optional[ArangoError]:
548
"""Error if operation failed."""
549
550
@property
551
def is_success(self) -> bool:
552
"""True if operation succeeded."""
553
```
554
555
## Usage Examples
556
557
### Exception Handling
558
559
```python
560
from arango import (
561
ArangoClient,
562
ArangoServerError,
563
DocumentInsertError,
564
CollectionCreateError,
565
AQLQueryExecuteError
566
)
567
568
client = ArangoClient()
569
db = client.db('example', username='root', password='password')
570
571
# Handle specific exceptions
572
try:
573
# Try to create collection
574
collection = db.create_collection('users')
575
576
# Try to insert document
577
result = collection.insert({'name': 'Alice', 'age': 25})
578
579
# Try to execute query
580
cursor = db.aql.execute('FOR u IN users RETURN u')
581
users = list(cursor)
582
583
except CollectionCreateError as e:
584
print(f"Failed to create collection: {e.error_message}")
585
print(f"Error code: {e.error_code}")
586
587
except DocumentInsertError as e:
588
print(f"Failed to insert document: {e.error_message}")
589
if e.error_code == 1210: # ERROR_ARANGO_CROSS_COLLECTION_REQUEST
590
print("Cross-collection request not allowed")
591
592
except AQLQueryExecuteError as e:
593
print(f"Query failed: {e.error_message}")
594
print(f"HTTP code: {e.http_code}")
595
596
except ArangoServerError as e:
597
print(f"Server error: {e.error_message}")
598
599
except Exception as e:
600
print(f"Unexpected error: {e}")
601
```
602
603
### Error Code Handling
604
605
```python
606
import arango.errno as errno
607
from arango import ArangoServerError
608
609
def handle_operation_with_error_codes(collection, document):
610
try:
611
result = collection.insert(document)
612
return result
613
614
except ArangoServerError as e:
615
if e.error_code == errno.ERROR_ARANGO_DUPLICATE_NAME:
616
print("Document key already exists")
617
# Try update instead
618
return collection.update(document)
619
620
elif e.error_code == errno.ERROR_ARANGO_DOCUMENT_TOO_LARGE:
621
print("Document too large, splitting...")
622
# Handle large document
623
624
elif e.error_code == errno.ERROR_ARANGO_VALIDATION_FAILED:
625
print("Document validation failed")
626
print(f"Details: {e.error_message}")
627
628
elif e.error_code == errno.ERROR_ARANGO_READ_ONLY:
629
print("Database is read-only")
630
631
else:
632
print(f"Unhandled server error: {e.error_code} - {e.error_message}")
633
raise
634
```
635
636
### Custom Error Handling
637
638
```python
639
class DatabaseOperationError(Exception):
640
"""Custom application-level error."""
641
642
def __init__(self, operation: str, arango_error: ArangoError):
643
self.operation = operation
644
self.arango_error = arango_error
645
super().__init__(f"Failed to {operation}: {arango_error.error_message}")
646
647
def safe_database_operation(db, operation_func, *args, **kwargs):
648
"""Wrapper for safe database operations."""
649
try:
650
return operation_func(*args, **kwargs)
651
652
except DocumentInsertError as e:
653
raise DatabaseOperationError("insert document", e)
654
655
except DocumentUpdateError as e:
656
raise DatabaseOperationError("update document", e)
657
658
except CollectionCreateError as e:
659
raise DatabaseOperationError("create collection", e)
660
661
except AQLQueryExecuteError as e:
662
raise DatabaseOperationError("execute query", e)
663
664
except ArangoServerError as e:
665
raise DatabaseOperationError("perform database operation", e)
666
667
# Usage
668
try:
669
collection = db.collection('users')
670
result = safe_database_operation(
671
db,
672
collection.insert,
673
{'name': 'Bob', 'age': 30}
674
)
675
676
except DatabaseOperationError as e:
677
print(f"Application error: {e}")
678
print(f"Original ArangoDB error: {e.arango_error.error_code}")
679
680
# Log for debugging
681
import logging
682
logging.error(f"Database operation failed", extra={
683
'operation': e.operation,
684
'error_code': e.arango_error.error_code,
685
'error_message': e.arango_error.error_message,
686
'http_code': e.arango_error.http_code
687
})
688
```
689
690
### Result Pattern Usage
691
692
```python
693
def process_documents_safely(collection, documents):
694
"""Process documents with comprehensive error handling."""
695
results = {
696
'success': [],
697
'errors': [],
698
'skipped': []
699
}
700
701
for doc in documents:
702
try:
703
# Validate document first
704
if not doc.get('name'):
705
results['skipped'].append({
706
'document': doc,
707
'reason': 'Missing required field: name'
708
})
709
continue
710
711
# Try to insert
712
result = collection.insert(doc, silent=False)
713
results['success'].append({
714
'document': doc,
715
'key': result['_key'],
716
'rev': result['_rev']
717
})
718
719
except DocumentInsertError as e:
720
results['errors'].append({
721
'document': doc,
722
'error': e.error_message,
723
'error_code': e.error_code
724
})
725
726
return results
727
728
# Usage
729
documents = [
730
{'name': 'Alice', 'age': 25},
731
{'name': 'Bob'}, # Missing age
732
{'age': 30}, # Missing name - will be skipped
733
{'name': 'Charlie', 'age': 35}
734
]
735
736
results = process_documents_safely(collection, documents)
737
print(f"Processed: {len(results['success'])} success, "
738
f"{len(results['errors'])} errors, "
739
f"{len(results['skipped'])} skipped")
740
```