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__( 

114 self, message: str | None = None, lock_name: str | None = None 

115 ) -> None: 

116 super().__init__(message) 

117 self.message = message 

118 self.lock_name = lock_name 

119 

120 

121class LockNotOwnedError(LockError): 

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

123 

124 pass 

125 

126 

127class ChildDeadlockedError(Exception): 

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

129 

130 pass 

131 

132 

133class AuthenticationWrongNumberOfArgsError(ResponseError): 

134 """ 

135 An error to indicate that the wrong number of args 

136 were sent to the AUTH command 

137 """ 

138 

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

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

141 self.error_type = ExceptionType.AUTH 

142 

143 

144class RedisClusterException(Exception): 

145 """ 

146 Base exception for the RedisCluster client 

147 """ 

148 

149 def __init__(self, *args: object) -> None: 

150 super().__init__(*args) 

151 self.error_type = ExceptionType.SERVER 

152 

153 def __repr__(self): 

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

155 

156 

157class ClusterError(RedisError): 

158 """ 

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

160 command execution TTL 

161 """ 

162 

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

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

165 self.error_type = ExceptionType.SERVER 

166 

167 

168class ClusterDownError(ClusterError, ResponseError): 

169 """ 

170 Error indicated CLUSTERDOWN error received from cluster. 

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

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

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

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

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

176 are covered again. 

177 """ 

178 

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

180 self.args = (resp,) 

181 self.message = resp 

182 self.error_type = ExceptionType.SERVER 

183 self.status_code = status_code 

184 

185 

186class AskError(ResponseError): 

187 """ 

188 Error indicated ASK error received from cluster. 

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

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

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

192 is target of the migration. 

193 

194 src node: MIGRATING to dst node 

195 get > ASK error 

196 ask dst node > ASKING command 

197 dst node: IMPORTING from src node 

198 asking command only affects next command 

199 any op will be allowed after asking command 

200 """ 

201 

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

203 """should only redirect to master node""" 

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

205 self.args = (resp,) 

206 self.message = resp 

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

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

209 self.slot_id = int(slot_id) 

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

211 

212 

213class TryAgainError(ResponseError): 

214 """ 

215 Error indicated TRYAGAIN error received from cluster. 

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

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

218 """ 

219 

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

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

222 

223 

224class ClusterCrossSlotError(ResponseError): 

225 """ 

226 Error indicated CROSSSLOT error received from cluster. 

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

228 same slot. 

229 """ 

230 

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

232 

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

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

235 self.error_type = ExceptionType.SERVER 

236 

237 

238class MovedError(AskError): 

239 """ 

240 Error indicated MOVED error received from cluster. 

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

242 a MOVED error that points to the correct node. 

243 """ 

244 

245 pass 

246 

247 

248class MasterDownError(ClusterDownError): 

249 """ 

250 Error indicated MASTERDOWN error received from cluster. 

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

252 """ 

253 

254 pass 

255 

256 

257class SlotNotCoveredError(RedisClusterException): 

258 """ 

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

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

261 

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

263 attempt to reconnect and refresh the node layout again 

264 """ 

265 

266 pass 

267 

268 

269class MaxConnectionsError(ConnectionError): 

270 """ 

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

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

273 """ 

274 

275 pass 

276 

277 

278class CrossSlotTransactionError(RedisClusterException): 

279 """ 

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

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

282 """ 

283 

284 pass 

285 

286 

287class InvalidPipelineStack(RedisClusterException): 

288 """ 

289 Raised on unexpected response length on pipelines. This is 

290 most likely a handling error on the stack. 

291 """ 

292 

293 pass 

294 

295 

296class ExternalAuthProviderError(ConnectionError): 

297 """ 

298 Raised when an external authentication provider returns an error. 

299 """ 

300 

301 pass 

302 

303 

304class IncorrectPolicyType(Exception): 

305 """ 

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

307 """ 

308 

309 pass