1"Core exceptions raised by the Redis client"
2
3
4class RedisError(Exception):
5 pass
6
7
8class ConnectionError(RedisError):
9 pass
10
11
12class TimeoutError(RedisError):
13 pass
14
15
16class AuthenticationError(ConnectionError):
17 pass
18
19
20class AuthorizationError(ConnectionError):
21 pass
22
23
24class BusyLoadingError(ConnectionError):
25 pass
26
27
28class InvalidResponse(RedisError):
29 pass
30
31
32class ResponseError(RedisError):
33 pass
34
35
36class DataError(RedisError):
37 pass
38
39
40class PubSubError(RedisError):
41 pass
42
43
44class WatchError(RedisError):
45 pass
46
47
48class NoScriptError(ResponseError):
49 pass
50
51
52class OutOfMemoryError(ResponseError):
53 """
54 Indicates the database is full. Can only occur when either:
55 * Redis maxmemory-policy=noeviction
56 * Redis maxmemory-policy=volatile* and there are no evictable keys
57
58 For more information see `Memory optimization in Redis <https://redis.io/docs/management/optimization/memory-optimization/#memory-allocation>`_. # noqa
59 """
60
61 pass
62
63
64class ExecAbortError(ResponseError):
65 pass
66
67
68class ReadOnlyError(ResponseError):
69 pass
70
71
72class NoPermissionError(ResponseError):
73 pass
74
75
76class ModuleError(ResponseError):
77 pass
78
79
80class LockError(RedisError, ValueError):
81 "Errors acquiring or releasing a lock"
82
83 # NOTE: For backwards compatibility, this class derives from ValueError.
84 # This was originally chosen to behave like threading.Lock.
85
86 def __init__(self, message=None, lock_name=None):
87 self.message = message
88 self.lock_name = lock_name
89
90
91class LockNotOwnedError(LockError):
92 "Error trying to extend or release a lock that is not owned (anymore)"
93
94 pass
95
96
97class ChildDeadlockedError(Exception):
98 "Error indicating that a child process is deadlocked after a fork()"
99
100 pass
101
102
103class AuthenticationWrongNumberOfArgsError(ResponseError):
104 """
105 An error to indicate that the wrong number of args
106 were sent to the AUTH command
107 """
108
109 pass
110
111
112class RedisClusterException(Exception):
113 """
114 Base exception for the RedisCluster client
115 """
116
117 pass
118
119
120class ClusterError(RedisError):
121 """
122 Cluster errors occurred multiple times, resulting in an exhaustion of the
123 command execution TTL
124 """
125
126 pass
127
128
129class ClusterDownError(ClusterError, ResponseError):
130 """
131 Error indicated CLUSTERDOWN error received from cluster.
132 By default Redis Cluster nodes stop accepting queries if they detect there
133 is at least a hash slot uncovered (no available node is serving it).
134 This way if the cluster is partially down (for example a range of hash
135 slots are no longer covered) the entire cluster eventually becomes
136 unavailable. It automatically returns available as soon as all the slots
137 are covered again.
138 """
139
140 def __init__(self, resp):
141 self.args = (resp,)
142 self.message = resp
143
144
145class AskError(ResponseError):
146 """
147 Error indicated ASK error received from cluster.
148 When a slot is set as MIGRATING, the node will accept all queries that
149 pertain to this hash slot, but only if the key in question exists,
150 otherwise the query is forwarded using a -ASK redirection to the node that
151 is target of the migration.
152
153 src node: MIGRATING to dst node
154 get > ASK error
155 ask dst node > ASKING command
156 dst node: IMPORTING from src node
157 asking command only affects next command
158 any op will be allowed after asking command
159 """
160
161 def __init__(self, resp):
162 """should only redirect to master node"""
163 self.args = (resp,)
164 self.message = resp
165 slot_id, new_node = resp.split(" ")
166 host, port = new_node.rsplit(":", 1)
167 self.slot_id = int(slot_id)
168 self.node_addr = self.host, self.port = host, int(port)
169
170
171class TryAgainError(ResponseError):
172 """
173 Error indicated TRYAGAIN error received from cluster.
174 Operations on keys that don't exist or are - during resharding - split
175 between the source and destination nodes, will generate a -TRYAGAIN error.
176 """
177
178 def __init__(self, *args, **kwargs):
179 pass
180
181
182class ClusterCrossSlotError(ResponseError):
183 """
184 Error indicated CROSSSLOT error received from cluster.
185 A CROSSSLOT error is generated when keys in a request don't hash to the
186 same slot.
187 """
188
189 message = "Keys in request don't hash to the same slot"
190
191
192class MovedError(AskError):
193 """
194 Error indicated MOVED error received from cluster.
195 A request sent to a node that doesn't serve this key will be replayed with
196 a MOVED error that points to the correct node.
197 """
198
199 pass
200
201
202class MasterDownError(ClusterDownError):
203 """
204 Error indicated MASTERDOWN error received from cluster.
205 Link with MASTER is down and replica-serve-stale-data is set to 'no'.
206 """
207
208 pass
209
210
211class SlotNotCoveredError(RedisClusterException):
212 """
213 This error only happens in the case where the connection pool will try to
214 fetch what node that is covered by a given slot.
215
216 If this error is raised the client should drop the current node layout and
217 attempt to reconnect and refresh the node layout again
218 """
219
220 pass
221
222
223class MaxConnectionsError(ConnectionError): ...
224
225
226class CrossSlotTransactionError(RedisClusterException):
227 """
228 Raised when a transaction or watch is triggered in a pipeline
229 and not all keys or all commands belong to the same slot.
230 """
231
232 pass
233
234
235class InvalidPipelineStack(RedisClusterException):
236 """
237 Raised on unexpected response length on pipelines. This is
238 most likely a handling error on the stack.
239 """
240
241 pass