0
# Error Handling
1
2
Comprehensive exception hierarchy representing all EdgeDB server errors and client-side issues, providing detailed error context and handling strategies.
3
4
## Capabilities
5
6
### Base Error Classes
7
8
Foundation classes for all EdgeDB errors and messages.
9
10
```python { .api }
11
class EdgeDBError(Exception):
12
"""
13
Base class for all EdgeDB errors.
14
15
Provides common error attributes and methods for accessing
16
error details, server context, and error classification.
17
"""
18
19
def has_tag(self, tag: ErrorTag) -> bool:
20
"""
21
Check if error has specific tag.
22
23
Parameters:
24
- tag: Error tag to check for
25
26
Returns:
27
True if error has the specified tag
28
"""
29
30
def get_code(self) -> int:
31
"""
32
Get error code.
33
34
Returns:
35
Numeric error code from EdgeDB server
36
"""
37
38
def get_server_context(self) -> Optional[str]:
39
"""
40
Get server context information.
41
42
Returns:
43
Server-side context information if available
44
"""
45
46
@property
47
def position(self) -> Optional[int]:
48
"""Position in query where error occurred."""
49
50
@property
51
def line(self) -> Optional[int]:
52
"""Line number where error occurred."""
53
54
@property
55
def col(self) -> Optional[int]:
56
"""Column number where error occurred."""
57
58
@property
59
def hint(self) -> Optional[str]:
60
"""Hint for resolving the error."""
61
62
@property
63
def details(self) -> Optional[str]:
64
"""Detailed error information."""
65
66
class EdgeDBMessage(Warning):
67
"""
68
Base class for EdgeDB messages and warnings.
69
70
Represents non-error messages from the database server.
71
"""
72
73
def get_severity(self) -> str:
74
"""Get message severity level."""
75
76
def get_severity_name(self) -> str:
77
"""Get human-readable severity name."""
78
79
def get_code(self) -> int:
80
"""Get message code."""
81
```
82
83
### Server Error Classes
84
85
Errors originating from the EdgeDB server.
86
87
```python { .api }
88
class InternalServerError(EdgeDBError):
89
"""Internal server error."""
90
91
class UnsupportedFeatureError(EdgeDBError):
92
"""Feature not supported by the server."""
93
94
class ProtocolError(EdgeDBError):
95
"""Protocol-level communication error."""
96
97
class BinaryProtocolError(ProtocolError):
98
"""Binary protocol parsing error."""
99
100
class UnsupportedProtocolVersionError(ProtocolError):
101
"""Unsupported protocol version."""
102
103
class TypeSpecNotFoundError(ProtocolError):
104
"""Type specification not found."""
105
106
class UnexpectedMessageError(ProtocolError):
107
"""Unexpected protocol message."""
108
109
class InputDataError(ProtocolError):
110
"""Invalid input data format."""
111
112
class ParameterTypeMismatchError(InputDataError):
113
"""Query parameter type mismatch."""
114
115
class StateMismatchError(ProtocolError):
116
"""Client-server state mismatch."""
117
118
class ResultCardinalityMismatchError(ProtocolError):
119
"""Query result cardinality mismatch."""
120
```
121
122
### Capability Errors
123
124
Errors related to EdgeDB capabilities and features.
125
126
```python { .api }
127
class CapabilityError(EdgeDBError):
128
"""Capability-related error."""
129
130
class UnsupportedCapabilityError(CapabilityError):
131
"""Requested capability not supported."""
132
133
class DisabledCapabilityError(CapabilityError):
134
"""Requested capability is disabled."""
135
```
136
137
### Query Errors
138
139
Errors in query syntax, semantics, and structure.
140
141
```python { .api }
142
class QueryError(EdgeDBError):
143
"""Base class for query-related errors."""
144
145
class InvalidSyntaxError(QueryError):
146
"""Invalid query syntax."""
147
148
class EdgeQLSyntaxError(InvalidSyntaxError):
149
"""EdgeQL syntax error."""
150
151
class SchemaSyntaxError(InvalidSyntaxError):
152
"""Schema definition syntax error."""
153
154
class GraphQLSyntaxError(InvalidSyntaxError):
155
"""GraphQL syntax error."""
156
157
class InvalidTypeError(QueryError):
158
"""Invalid type usage."""
159
160
class InvalidTargetError(InvalidTypeError):
161
"""Invalid target for operation."""
162
163
class InvalidLinkTargetError(InvalidTargetError):
164
"""Invalid link target."""
165
166
class InvalidPropertyTargetError(InvalidTargetError):
167
"""Invalid property target."""
168
169
class InvalidReferenceError(QueryError):
170
"""Invalid reference in query."""
171
172
class UnknownModuleError(InvalidReferenceError):
173
"""Reference to unknown module."""
174
175
class UnknownLinkError(InvalidReferenceError):
176
"""Reference to unknown link."""
177
178
class UnknownPropertyError(InvalidReferenceError):
179
"""Reference to unknown property."""
180
181
class UnknownUserError(InvalidReferenceError):
182
"""Reference to unknown user."""
183
184
class UnknownDatabaseError(InvalidReferenceError):
185
"""Reference to unknown database."""
186
187
class UnknownParameterError(InvalidReferenceError):
188
"""Reference to unknown parameter."""
189
```
190
191
### Schema Errors
192
193
Errors in schema definition and modification.
194
195
```python { .api }
196
class SchemaError(EdgeDBError):
197
"""Base class for schema-related errors."""
198
199
class SchemaDefinitionError(SchemaError):
200
"""Schema definition error."""
201
202
class InvalidDefinitionError(SchemaDefinitionError):
203
"""Invalid schema definition."""
204
205
class InvalidModuleDefinitionError(InvalidDefinitionError):
206
"""Invalid module definition."""
207
208
class InvalidLinkDefinitionError(InvalidDefinitionError):
209
"""Invalid link definition."""
210
211
class InvalidPropertyDefinitionError(InvalidDefinitionError):
212
"""Invalid property definition."""
213
214
class InvalidUserDefinitionError(InvalidDefinitionError):
215
"""Invalid user definition."""
216
217
class InvalidDatabaseDefinitionError(InvalidDefinitionError):
218
"""Invalid database definition."""
219
220
class InvalidOperatorDefinitionError(InvalidDefinitionError):
221
"""Invalid operator definition."""
222
223
class InvalidAliasDefinitionError(InvalidDefinitionError):
224
"""Invalid alias definition."""
225
226
class InvalidFunctionDefinitionError(InvalidDefinitionError):
227
"""Invalid function definition."""
228
229
class InvalidConstraintDefinitionError(InvalidDefinitionError):
230
"""Invalid constraint definition."""
231
232
class InvalidCastDefinitionError(InvalidDefinitionError):
233
"""Invalid cast definition."""
234
235
class DuplicateDefinitionError(SchemaDefinitionError):
236
"""Duplicate schema definition."""
237
238
class DuplicateModuleDefinitionError(DuplicateDefinitionError):
239
"""Duplicate module definition."""
240
241
class DuplicateLinkDefinitionError(DuplicateDefinitionError):
242
"""Duplicate link definition."""
243
244
class DuplicatePropertyDefinitionError(DuplicateDefinitionError):
245
"""Duplicate property definition."""
246
247
class DuplicateUserDefinitionError(DuplicateDefinitionError):
248
"""Duplicate user definition."""
249
250
class DuplicateDatabaseDefinitionError(DuplicateDefinitionError):
251
"""Duplicate database definition."""
252
253
class DuplicateOperatorDefinitionError(DuplicateDefinitionError):
254
"""Duplicate operator definition."""
255
256
class DuplicateViewDefinitionError(DuplicateDefinitionError):
257
"""Duplicate view definition."""
258
259
class DuplicateFunctionDefinitionError(DuplicateDefinitionError):
260
"""Duplicate function definition."""
261
262
class DuplicateConstraintDefinitionError(DuplicateDefinitionError):
263
"""Duplicate constraint definition."""
264
265
class DuplicateCastDefinitionError(DuplicateDefinitionError):
266
"""Duplicate cast definition."""
267
268
class DuplicateMigrationError(DuplicateDefinitionError):
269
"""Duplicate migration definition."""
270
```
271
272
### Execution Errors
273
274
Errors during query and command execution.
275
276
```python { .api }
277
class ExecutionError(EdgeDBError):
278
"""Base class for execution errors."""
279
280
class InvalidValueError(ExecutionError):
281
"""Invalid value for operation."""
282
283
class DivisionByZeroError(ExecutionError):
284
"""Division by zero error."""
285
286
class NumericOutOfRangeError(ExecutionError):
287
"""Numeric value out of range."""
288
289
class AccessPolicyError(ExecutionError):
290
"""Access policy violation."""
291
292
class QueryAssertionError(ExecutionError):
293
"""Query assertion failed."""
294
295
class IntegrityError(ExecutionError):
296
"""Database integrity constraint violation."""
297
298
class ConstraintViolationError(IntegrityError):
299
"""General constraint violation."""
300
301
class CardinalityViolationError(ConstraintViolationError):
302
"""Cardinality constraint violation."""
303
304
class MissingRequiredError(ConstraintViolationError):
305
"""Required value missing."""
306
```
307
308
### Transaction Errors
309
310
Errors related to transaction management.
311
312
```python { .api }
313
class TransactionError(EdgeDBError):
314
"""Base class for transaction errors."""
315
316
class TransactionConflictError(TransactionError):
317
"""Transaction conflict detected."""
318
319
class TransactionSerializationError(TransactionError):
320
"""Transaction serialization failure."""
321
322
class TransactionDeadlockError(TransactionError):
323
"""Transaction deadlock detected."""
324
325
class WatchError(TransactionError):
326
"""Watch operation error."""
327
```
328
329
### Timeout Errors
330
331
Errors related to timeouts and time limits.
332
333
```python { .api }
334
class SessionTimeoutError(EdgeDBError):
335
"""Session timeout exceeded."""
336
337
class IdleSessionTimeoutError(SessionTimeoutError):
338
"""Idle session timeout exceeded."""
339
340
class QueryTimeoutError(EdgeDBError):
341
"""Query execution timeout."""
342
343
class TransactionTimeoutError(EdgeDBError):
344
"""Transaction timeout exceeded."""
345
346
class IdleTransactionTimeoutError(TransactionTimeoutError):
347
"""Idle transaction timeout exceeded."""
348
```
349
350
### Client Errors
351
352
Errors originating from the client side.
353
354
```python { .api }
355
class ClientError(EdgeDBError):
356
"""Base class for client-side errors."""
357
358
class ClientConnectionError(ClientError):
359
"""Client connection error."""
360
361
class ClientConnectionFailedError(ClientConnectionError):
362
"""Connection to server failed."""
363
364
class ClientConnectionFailedTemporarilyError(ClientConnectionFailedError):
365
"""Temporary connection failure."""
366
367
class ClientConnectionTimeoutError(ClientConnectionError):
368
"""Connection timeout."""
369
370
class ClientConnectionClosedError(ClientConnectionError):
371
"""Connection closed unexpectedly."""
372
373
class InterfaceError(ClientError):
374
"""Client interface usage error."""
375
376
class QueryArgumentError(InterfaceError):
377
"""Invalid query arguments."""
378
379
class MissingArgumentError(QueryArgumentError):
380
"""Required argument missing."""
381
382
class UnknownArgumentError(QueryArgumentError):
383
"""Unknown argument provided."""
384
385
class InvalidArgumentError(QueryArgumentError):
386
"""Invalid argument value."""
387
388
class NoDataError(InterfaceError):
389
"""No data returned when data expected."""
390
391
class InternalClientError(ClientError):
392
"""Internal client error."""
393
```
394
395
### Access and Authentication Errors
396
397
Errors related to access control and authentication.
398
399
```python { .api }
400
class ConfigurationError(EdgeDBError):
401
"""Configuration error."""
402
403
class AccessError(EdgeDBError):
404
"""Access control error."""
405
406
class AuthenticationError(AccessError):
407
"""Authentication failed."""
408
409
class AvailabilityError(EdgeDBError):
410
"""Server availability error."""
411
412
class BackendUnavailableError(AvailabilityError):
413
"""Backend server unavailable."""
414
415
class ServerOfflineError(AvailabilityError):
416
"""Server is offline."""
417
418
class BackendError(EdgeDBError):
419
"""Backend server error."""
420
421
class UnsupportedBackendFeatureError(BackendError):
422
"""Backend feature not supported."""
423
```
424
425
### Message Classes
426
427
Non-error messages from the database.
428
429
```python { .api }
430
class LogMessage(EdgeDBMessage):
431
"""Log message from server."""
432
433
class WarningMessage(EdgeDBMessage):
434
"""Warning message from server."""
435
```
436
437
## Usage Examples
438
439
### Basic Error Handling
440
441
```python
442
import edgedb
443
444
client = edgedb.create_client()
445
446
try:
447
user = client.query_required_single(
448
"SELECT User { name } FILTER .email = $email",
449
email="nonexistent@example.com"
450
)
451
except edgedb.NoDataError:
452
print("User not found")
453
except edgedb.QueryArgumentError as e:
454
print(f"Invalid query arguments: {e}")
455
except edgedb.EdgeDBError as e:
456
print(f"Database error: {e}")
457
```
458
459
### Specific Error Types
460
461
```python
462
import edgedb
463
464
client = edgedb.create_client()
465
466
try:
467
client.execute("""
468
INSERT User {
469
name := 'John Doe',
470
email := 'john@example.com'
471
}
472
""")
473
except edgedb.ConstraintViolationError as e:
474
print(f"Constraint violation: {e}")
475
# Handle duplicate email, etc.
476
except edgedb.InvalidValueError as e:
477
print(f"Invalid value: {e}")
478
# Handle invalid data format
479
except edgedb.SchemaError as e:
480
print(f"Schema error: {e}")
481
# Handle schema-related issues
482
```
483
484
### Transaction Error Handling
485
486
```python
487
import edgedb
488
489
client = edgedb.create_client()
490
491
max_retries = 3
492
for attempt in range(max_retries):
493
try:
494
with client.transaction() as tx:
495
tx.execute("UPDATE Account SET balance = balance - 100 WHERE id = $1", account_id)
496
tx.execute("UPDATE Account SET balance = balance + 100 WHERE id = $2", target_id)
497
break # Success, exit retry loop
498
499
except edgedb.TransactionConflictError:
500
if attempt == max_retries - 1:
501
raise # Last attempt failed
502
print(f"Transaction conflict, retrying... (attempt {attempt + 1})")
503
504
except edgedb.TransactionSerializationError:
505
if attempt == max_retries - 1:
506
raise
507
print(f"Serialization error, retrying... (attempt {attempt + 1})")
508
```
509
510
### Connection Error Handling
511
512
```python
513
import edgedb
514
import time
515
516
def create_client_with_retry():
517
max_attempts = 5
518
base_delay = 1.0
519
520
for attempt in range(max_attempts):
521
try:
522
return edgedb.create_client()
523
except edgedb.ClientConnectionFailedError as e:
524
if attempt == max_attempts - 1:
525
raise # Last attempt
526
527
delay = base_delay * (2 ** attempt) # Exponential backoff
528
print(f"Connection failed, retrying in {delay}s... (attempt {attempt + 1})")
529
time.sleep(delay)
530
531
except edgedb.ClientConnectionTimeoutError:
532
print("Connection timeout, check network connectivity")
533
raise
534
535
except edgedb.AuthenticationError:
536
print("Authentication failed, check credentials")
537
raise
538
539
client = create_client_with_retry()
540
```
541
542
### Query Error Analysis
543
544
```python
545
import edgedb
546
547
client = edgedb.create_client()
548
549
try:
550
result = client.query("SELECT User { name, email } WHERE .invalid_field = 'value'")
551
except edgedb.InvalidReferenceError as e:
552
print(f"Invalid reference: {e}")
553
print(f"Error position: line {e.line}, column {e.col}")
554
print(f"Hint: {e.hint}")
555
556
except edgedb.EdgeQLSyntaxError as e:
557
print(f"Syntax error: {e}")
558
print(f"Error at position {e.position}")
559
if e.details:
560
print(f"Details: {e.details}")
561
```
562
563
### Comprehensive Error Handler
564
565
```python
566
import edgedb
567
import logging
568
569
logger = logging.getLogger(__name__)
570
571
def handle_edgedb_error(e: edgedb.EdgeDBError, operation: str) -> None:
572
"""Comprehensive EdgeDB error handler."""
573
574
error_code = e.get_code() if hasattr(e, 'get_code') else None
575
576
if isinstance(e, edgedb.NoDataError):
577
logger.warning(f"{operation}: No data found")
578
579
elif isinstance(e, edgedb.ConstraintViolationError):
580
logger.error(f"{operation}: Constraint violation - {e}")
581
582
elif isinstance(e, edgedb.TransactionConflictError):
583
logger.warning(f"{operation}: Transaction conflict - {e}")
584
585
elif isinstance(e, edgedb.QueryArgumentError):
586
logger.error(f"{operation}: Invalid arguments - {e}")
587
588
elif isinstance(e, edgedb.InvalidSyntaxError):
589
logger.error(f"{operation}: Syntax error at line {e.line}, col {e.col} - {e}")
590
591
elif isinstance(e, edgedb.ClientConnectionError):
592
logger.error(f"{operation}: Connection error - {e}")
593
594
elif isinstance(e, edgedb.AuthenticationError):
595
logger.error(f"{operation}: Authentication failed - {e}")
596
597
elif isinstance(e, edgedb.QueryTimeoutError):
598
logger.error(f"{operation}: Query timeout - {e}")
599
600
else:
601
logger.error(f"{operation}: Unknown EdgeDB error ({error_code}) - {e}")
602
603
# Usage
604
try:
605
users = client.query("SELECT User { name, email }")
606
except edgedb.EdgeDBError as e:
607
handle_edgedb_error(e, "fetch_users")
608
```
609
610
### Context Manager for Error Handling
611
612
```python
613
import edgedb
614
from contextlib import contextmanager
615
from typing import Generator, Optional, Type, Union
616
617
@contextmanager
618
def edgedb_error_context(
619
operation: str,
620
reraise: bool = True,
621
ignore_errors: Optional[Union[Type[Exception], tuple]] = None
622
) -> Generator[None, None, None]:
623
"""Context manager for EdgeDB error handling."""
624
625
try:
626
yield
627
except Exception as e:
628
if ignore_errors and isinstance(e, ignore_errors):
629
return
630
631
if isinstance(e, edgedb.EdgeDBError):
632
print(f"EdgeDB error in {operation}: {e}")
633
if hasattr(e, 'hint') and e.hint:
634
print(f"Hint: {e.hint}")
635
else:
636
print(f"Unexpected error in {operation}: {e}")
637
638
if reraise:
639
raise
640
641
# Usage
642
client = edgedb.create_client()
643
644
with edgedb_error_context("user_creation"):
645
client.execute("INSERT User { name := 'Alice', email := 'alice@example.com' }")
646
647
# Ignore specific errors
648
with edgedb_error_context("optional_update", ignore_errors=edgedb.NoDataError):
649
client.execute("UPDATE User FILTER .email = 'nonexistent@example.com' SET { active := false }")
650
```
651
652
### Error Recovery Strategies
653
654
```python
655
import edgedb
656
from typing import Any, Callable, Optional
657
658
def with_fallback(
659
primary_operation: Callable[[], Any],
660
fallback_operation: Optional[Callable[[], Any]] = None,
661
fallback_errors: tuple = (edgedb.NoDataError, edgedb.QueryTimeoutError)
662
) -> Any:
663
"""Execute operation with fallback on specific errors."""
664
665
try:
666
return primary_operation()
667
except fallback_errors as e:
668
print(f"Primary operation failed ({type(e).__name__}), using fallback")
669
if fallback_operation:
670
return fallback_operation()
671
return None
672
except edgedb.EdgeDBError:
673
raise # Re-raise other EdgeDB errors
674
675
# Usage
676
client = edgedb.create_client()
677
678
def get_user_expensive():
679
"""Expensive query with complex computation."""
680
return client.query_single("SELECT compute_user_stats($id)", id=user_id)
681
682
def get_user_basic():
683
"""Simple fallback query."""
684
return client.query_single("SELECT User { name } FILTER .id = $id", id=user_id)
685
686
user_id = "123e4567-e89b-12d3-a456-426614174000"
687
user = with_fallback(get_user_expensive, get_user_basic)
688
```