1class Error(Exception):
2 pass
3
4
5class InterfaceError(Error):
6 pass
7
8
9class DatabaseError(Error):
10 pass
11
12
13class DataError(DatabaseError):
14 pass
15
16
17class OperationalError(DatabaseError):
18 pass
19
20
21class IntegrityError(DatabaseError):
22 pass
23
24
25class InternalError(DatabaseError):
26 pass
27
28
29class ProgrammingError(DatabaseError):
30 pass
31
32
33class NotSupportedError(DatabaseError):
34 pass
35
36
37class ConnectionDoesNotExist(Exception):
38 pass
39
40
41class DatabaseErrorWrapper:
42 """
43 Context manager and decorator that reraises backend-specific database
44 exceptions using Plain's common wrappers.
45 """
46
47 def __init__(self, wrapper):
48 """
49 wrapper is a database wrapper.
50
51 It must have a Database attribute defining PEP-249 exceptions.
52 """
53 self.wrapper = wrapper
54
55 def __enter__(self):
56 pass
57
58 def __exit__(self, exc_type, exc_value, traceback):
59 if exc_type is None:
60 return
61 for plain_exc_type in (
62 DataError,
63 OperationalError,
64 IntegrityError,
65 InternalError,
66 ProgrammingError,
67 NotSupportedError,
68 DatabaseError,
69 InterfaceError,
70 Error,
71 ):
72 db_exc_type = getattr(self.wrapper.Database, plain_exc_type.__name__)
73 if issubclass(exc_type, db_exc_type):
74 plain_exc_value = plain_exc_type(*exc_value.args)
75 # Only set the 'errors_occurred' flag for errors that may make
76 # the connection unusable.
77 if plain_exc_type not in (DataError, IntegrityError):
78 self.wrapper.errors_occurred = True
79 raise plain_exc_value.with_traceback(traceback) from exc_value
80
81 def __call__(self, func):
82 # Note that we are intentionally not using @wraps here for performance
83 # reasons. Refs #21109.
84 def inner(*args, **kwargs):
85 with self:
86 return func(*args, **kwargs)
87
88 return inner