Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/redis/exceptions.py: 67%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

120 statements  

1from enum import Enum 

2 

3"Core exceptions raised by the Redis client" 

4 

5 

6class ExceptionType(Enum): 

7 NETWORK = "network" 

8 TLS = "tls" 

9 AUTH = "auth" 

10 SERVER = "server" 

11 

12 

13class RedisError(Exception): 

14 def __init__(self, *args, status_code: str = None): 

15 super().__init__(*args) 

16 self.error_type = ExceptionType.SERVER 

17 self.status_code = status_code 

18 

19 def __repr__(self): 

20 return f"{self.error_type.value}:{self.__class__.__name__}" 

21 

22 

23class ConnectionError(RedisError): 

24 def __init__(self, *args, status_code: str = None): 

25 super().__init__(*args, status_code=status_code) 

26 self.error_type = ExceptionType.NETWORK 

27 

28 

29class TimeoutError(RedisError): 

30 def __init__(self, *args, status_code: str = None): 

31 super().__init__(*args, status_code=status_code) 

32 self.error_type = ExceptionType.NETWORK 

33 

34 

35class AuthenticationError(ConnectionError): 

36 def __init__(self, *args, status_code: str = None): 

37 super().__init__(*args, status_code=status_code) 

38 self.error_type = ExceptionType.AUTH 

39 

40 

41class AuthorizationError(ConnectionError): 

42 def __init__(self, *args, status_code: str = None): 

43 super().__init__(*args, status_code=status_code) 

44 self.error_type = ExceptionType.AUTH 

45 

46 

47class BusyLoadingError(ConnectionError): 

48 def __init__(self, *args, status_code: str = None): 

49 super().__init__(*args, status_code=status_code) 

50 self.error_type = ExceptionType.NETWORK 

51 

52 

53class InvalidResponse(RedisError): 

54 pass 

55 

56 

57class ResponseError(RedisError): 

58 pass 

59 

60 

61class DataError(RedisError): 

62 pass 

63 

64 

65class PubSubError(RedisError): 

66 pass 

67 

68 

69class WatchError(RedisError): 

70 pass 

71 

72 

73class NoScriptError(ResponseError): 

74 pass 

75 

76 

77class OutOfMemoryError(ResponseError): 

78 """ 

79 Indicates the database is full. Can only occur when either: 

80 * Redis maxmemory-policy=noeviction 

81 * Redis maxmemory-policy=volatile* and there are no evictable keys 

82 

83 For more information see `Memory optimization in Redis <https://redis.io/docs/management/optimization/memory-optimization/#memory-allocation>`_. # noqa 

84 """ 

85 

86 pass 

87 

88 

89class ExecAbortError(ResponseError): 

90 pass 

91 

92 

93class ReadOnlyError(ResponseError): 

94 pass 

95 

96 

97class NoPermissionError(ResponseError): 

98 def __init__(self, *args, status_code: str = None): 

99 super().__init__(*args, status_code=status_code) 

100 self.error_type = ExceptionType.AUTH 

101 

102 

103class ModuleError(ResponseError): 

104 pass 

105 

106 

107class LockError(RedisError, ValueError): 

108 "Errors acquiring or releasing a lock" 

109 

110 # NOTE: For backwards compatibility, this class derives from ValueError. 

111 # This was originally chosen to behave like threading.Lock. 

112 

113 def __init__(self, message=None, lock_name=None): 

114 super().__init__(message) 

115 self.message = message 

116 self.lock_name = lock_name 

117 

118 

119class LockNotOwnedError(LockError): 

120 "Error trying to extend or release a lock that is not owned (anymore)" 

121 

122 pass 

123 

124 

125class ChildDeadlockedError(Exception): 

126 "Error indicating that a child process is deadlocked after a fork()" 

127 

128 pass 

129 

130 

131class AuthenticationWrongNumberOfArgsError(ResponseError): 

132 """ 

133 An error to indicate that the wrong number of args 

134 were sent to the AUTH command 

135 """ 

136 

137 def __init__(self, *args, status_code: str = None): 

138 super().__init__(*args, status_code=status_code) 

139 self.error_type = ExceptionType.AUTH 

140 

141 

142class RedisClusterException(Exception): 

143 """ 

144 Base exception for the RedisCluster client 

145 """ 

146 

147 def __init__(self, *args): 

148 super().__init__(*args) 

149 self.error_type = ExceptionType.SERVER 

150 

151 def __repr__(self): 

152 return f"{self.error_type.value}:{self.__class__.__name__}" 

153 

154 

155class ClusterError(RedisError): 

156 """ 

157 Cluster errors occurred multiple times, resulting in an exhaustion of the 

158 command execution TTL 

159 """ 

160 

161 def __init__(self, *args, status_code: str = None): 

162 super().__init__(*args, status_code=status_code) 

163 self.error_type = ExceptionType.SERVER 

164 

165 

166class ClusterDownError(ClusterError, ResponseError): 

167 """ 

168 Error indicated CLUSTERDOWN error received from cluster. 

169 By default Redis Cluster nodes stop accepting queries if they detect there 

170 is at least a hash slot uncovered (no available node is serving it). 

171 This way if the cluster is partially down (for example a range of hash 

172 slots are no longer covered) the entire cluster eventually becomes 

173 unavailable. It automatically returns available as soon as all the slots 

174 are covered again. 

175 """ 

176 

177 def __init__(self, resp, status_code: str = None): 

178 self.args = (resp,) 

179 self.message = resp 

180 self.error_type = ExceptionType.SERVER 

181 self.status_code = status_code 

182 

183 

184class AskError(ResponseError): 

185 """ 

186 Error indicated ASK error received from cluster. 

187 When a slot is set as MIGRATING, the node will accept all queries that 

188 pertain to this hash slot, but only if the key in question exists, 

189 otherwise the query is forwarded using a -ASK redirection to the node that 

190 is target of the migration. 

191 

192 src node: MIGRATING to dst node 

193 get > ASK error 

194 ask dst node > ASKING command 

195 dst node: IMPORTING from src node 

196 asking command only affects next command 

197 any op will be allowed after asking command 

198 """ 

199 

200 def __init__(self, resp, status_code: str = None): 

201 """should only redirect to master node""" 

202 super().__init__(resp, status_code=status_code) 

203 self.args = (resp,) 

204 self.message = resp 

205 slot_id, new_node = resp.split(" ") 

206 host, port = new_node.rsplit(":", 1) 

207 self.slot_id = int(slot_id) 

208 self.node_addr = self.host, self.port = host, int(port) 

209 

210 

211class TryAgainError(ResponseError): 

212 """ 

213 Error indicated TRYAGAIN error received from cluster. 

214 Operations on keys that don't exist or are - during resharding - split 

215 between the source and destination nodes, will generate a -TRYAGAIN error. 

216 """ 

217 

218 def __init__(self, *args, status_code: str = None, **kwargs): 

219 super().__init__(*args, status_code=status_code) 

220 

221 

222class ClusterCrossSlotError(ResponseError): 

223 """ 

224 Error indicated CROSSSLOT error received from cluster. 

225 A CROSSSLOT error is generated when keys in a request don't hash to the 

226 same slot. 

227 """ 

228 

229 message = "Keys in request don't hash to the same slot" 

230 

231 def __init__(self, *args, status_code: str = None): 

232 super().__init__(*args, status_code=status_code) 

233 self.error_type = ExceptionType.SERVER 

234 

235 

236class MovedError(AskError): 

237 """ 

238 Error indicated MOVED error received from cluster. 

239 A request sent to a node that doesn't serve this key will be replayed with 

240 a MOVED error that points to the correct node. 

241 """ 

242 

243 pass 

244 

245 

246class MasterDownError(ClusterDownError): 

247 """ 

248 Error indicated MASTERDOWN error received from cluster. 

249 Link with MASTER is down and replica-serve-stale-data is set to 'no'. 

250 """ 

251 

252 pass 

253 

254 

255class SlotNotCoveredError(RedisClusterException): 

256 """ 

257 This error only happens in the case where the connection pool will try to 

258 fetch what node that is covered by a given slot. 

259 

260 If this error is raised the client should drop the current node layout and 

261 attempt to reconnect and refresh the node layout again 

262 """ 

263 

264 pass 

265 

266 

267class MaxConnectionsError(ConnectionError): 

268 """ 

269 Raised when a connection pool has reached its max_connections limit. 

270 This indicates pool exhaustion rather than an actual connection failure. 

271 """ 

272 

273 pass 

274 

275 

276class CrossSlotTransactionError(RedisClusterException): 

277 """ 

278 Raised when a transaction or watch is triggered in a pipeline 

279 and not all keys or all commands belong to the same slot. 

280 """ 

281 

282 pass 

283 

284 

285class InvalidPipelineStack(RedisClusterException): 

286 """ 

287 Raised on unexpected response length on pipelines. This is 

288 most likely a handling error on the stack. 

289 """ 

290 

291 pass 

292 

293 

294class ExternalAuthProviderError(ConnectionError): 

295 """ 

296 Raised when an external authentication provider returns an error. 

297 """ 

298 

299 pass 

300 

301 

302class IncorrectPolicyType(Exception): 

303 """ 

304 Raised when a policy type isn't matching to any known policy types. 

305 """ 

306 

307 pass