Source code for coredis.exceptions

from __future__ import annotations

import re

from coredis.typing import Optional, Set, Tuple, ValueT


[docs] class RedisError(Exception): """ Base exception from which all other exceptions in coredis derive from. """
[docs] class CommandSyntaxError(RedisError): """ Raised when a redis command is called with an invalid syntax """ def __init__(self, arguments: Set[str], message: str) -> None: self.arguments: Set[str] = arguments super().__init__(message)
[docs] class CommandNotSupportedError(RedisError): """ Raised when the target server doesn't support a command due to version mismatch """ def __init__(self, cmd: str, current_version: str) -> None: super().__init__(f"{cmd} is not supported on server version {current_version}")
[docs] class ModuleCommandNotSupportedError(CommandNotSupportedError): """ Raised when the target server doesn't support a module command due to version mismatch of the module """ def __init__(self, cmd: str, module: str, current_version: str) -> None: RedisError.__init__( self, ( f"{cmd} is not supported on {module} version {current_version}" if current_version else f"{cmd} is not supported since Module: {module} is not available" ), )
[docs] class ConnectionError(RedisError): pass
class ProtocolError(ConnectionError): """ Raised on errors related to ser/deser protocol parsing """
[docs] class TimeoutError(RedisError): pass
[docs] class BusyLoadingError(ConnectionError): pass
[docs] class InvalidResponse(RedisError): pass
[docs] class ResponseError(RedisError): pass
[docs] class DataError(RedisError): pass
[docs] class NoKeyError(RedisError): """ Raised when a key provided in the command is missing """
[docs] class ReplicationError(RedisError): """ Raised when the replication requirements were not met """ def __init__(self, command: bytes, replicas: int, timeout: int): super().__init__( f"Command {str(command)} did not replicate to {replicas} replicas within {timeout} ms." )
[docs] class PersistenceError(RedisError): """ Raised when the persistence requirements were not met """ def __init__(self, command: bytes, local: int, replicas: int, timeout: int): super().__init__( f"Command {str(command)} did not sync to the aof of {local} hosts and/or {replicas} " f"replicas within {timeout} ms." )
[docs] class NotBusyError(ResponseError): """ Raised when script kill or function kill have nothing to terminate """
[docs] class UnblockedError(ResponseError): """ Raised if a blocked client is unblocked forcefully """
class WrongTypeError(ResponseError): """ Raised when an operation is performed on a key containing a datatype that doesn't support the operation """
[docs] class PubSubError(RedisError): pass
[docs] class WatchError(RedisError): pass
[docs] class NoScriptError(ResponseError): pass
[docs] class ExecAbortError(ResponseError): pass
[docs] class ReadOnlyError(ResponseError): pass
[docs] class LockError(RedisError, ValueError): """Errors acquiring or releasing a lock"""
# NOTE: For backwards compatability, this class derives from ValueError. # This was originally chosen to behave like threading.Lock.
[docs] class LockAcquisitionError(LockError): """Errors acquiring a lock"""
[docs] class LockReleaseError(LockError): """Errors releasing a lock"""
[docs] class LockExtensionError(LockError): """Errors extending a lock"""
[docs] class RedisClusterException(Exception): """Base exception for the RedisCluster client"""
[docs] class ClusterError(RedisError): """ Cluster errors occurred multiple times, resulting in an exhaustion of the command execution ``TTL`` """
[docs] class ClusterCrossSlotError(ResponseError): """Raised when keys in request don't hash to the same slot""" def __init__( self, message: Optional[str] = None, command: Optional[bytes] = None, keys: Optional[Tuple[ValueT, ...]] = None, ) -> None: super().__init__(message or "Keys in request don't hash to the same slot") self.command = command self.keys = keys
[docs] class ClusterRoutingError(RedisClusterException): """Raised when keys in request can't be routed to destination nodes"""
[docs] class ClusterDownError(ClusterError, ResponseError): """ Error indicated ``CLUSTERDOWN`` error received from cluster. By default Redis Cluster nodes stop accepting queries if they detect there is at least a hash slot uncovered (no available node is serving it). This way if the cluster is partially down (for example a range of hash slots are no longer covered) the entire cluster eventually becomes unavailable. It automatically returns available as soon as all the slots are covered again. """ def __init__(self, resp: str) -> None: self.args = (resp,) self.message = resp
[docs] class ClusterTransactionError(ClusterError): def __init__(self, msg: str) -> None: self.msg = msg
[docs] class ClusterResponseError(ClusterError): """ Raised when application logic to combine multi node cluster responses has errors. """
[docs] class AskError(ResponseError): """ Error indicated ``ASK`` error received from cluster. When a slot is set as ``MIGRATING``, the node will accept all queries that pertain to this hash slot, but only if the key in question exists, otherwise the query is forwarded using a -ASK redirection to the node that is target of the migration. src node: ``MIGRATING`` to dst node get > ``ASK`` error ask dst node > ``ASKING`` command dst node: ``IMPORTING`` from src node asking command only affects next command any op will be allowed after asking command """ def __init__(self, resp: str) -> None: self.args = (resp,) self.message = resp slot_id, new_node = resp.split(" ") host, port = new_node.rsplit(":", 1) self.slot_id = int(slot_id) self.node_addr = self.host, self.port = host, int(port)
[docs] class TryAgainError(ResponseError): """ Error indicated ``TRYAGAIN`` error received from cluster. Operations on keys that don't exist or are - during resharding - split between the source and destination nodes, will generate a -``TRYAGAIN`` error. """
[docs] class MovedError(AskError): """ Error indicated ``MOVED`` error received from cluster. A request sent to a node that doesn't serve this key will be replayed with a ``MOVED`` error that points to the correct node. """
class AuthenticationError(ResponseError): """ Base class for authentication errors """
[docs] class AuthenticationFailureError(AuthenticationError): """ Raised when authentication parameters were provided but were invalid """
[docs] class AuthenticationRequiredError(AuthenticationError): """ Raised when authentication parameters are required but not provided """
[docs] class AuthorizationError(ResponseError): """ Base class for authorization errors """
[docs] class FunctionError(RedisError): """ Raised for errors relating to redis functions """
class SentinelError(RedisError): pass
[docs] class PrimaryNotFoundError(SentinelError): """ Raised when a primary cannot be located in a sentinel managed redis """
[docs] class ReplicaNotFoundError(SentinelError): """ Raised when a replica cannot be located in a sentinel managed redis """
class UnknownCommandError(ResponseError): """ Raised when the server returns an error response relating to an unknown command. """ ERROR_REGEX = re.compile("unknown command (.*?)") #: Name of command requested command: str def __init__(self, message: str) -> None: command_match = self.ERROR_REGEX.findall(message) if command_match: self.command = command_match.pop() super().__init__(message) class StreamConsumerError(RedisError): """ Base exception for stream consumer related errors """ class StreamConsumerGroupError(StreamConsumerError): """ Base exception for consumer group related errors """
[docs] class StreamDuplicateConsumerGroupError(StreamConsumerGroupError): """ Raised when and attempt to create a stream consumer group fails because it already exists """
[docs] class StreamConsumerInitializationError(StreamConsumerError): """ Raised when a stream consumer could not be initialized based on the configuration provided """