Source code for aiobtclientrpc._errors

import re


[docs] class Error(Exception): """Base class for all exceptions raised by this package""" def __eq__(self, other): if isinstance(other, type(self)): return str(self) == str(other) else: return NotImplemented
[docs] class RPCError(Error): """ Generic RPC error This can be some kind of miscommunication with the RPC service (e.g. unknown method called, invalid or missing argument, etc), which should be a considered a bug. But it can also be a normal error message (e.g. unknown torrent), that should be communicated to the user. """ def __init__(self, msg, info=None): super().__init__(msg) self._info = info @property def info(self): """ """ return self._info def __repr__(self): return f'{type(self).__name__}({str(self)!r}, info={self._info!r})' def __eq__(self, other): equal = super().__eq__(other) if equal is True and hasattr(other, 'info'): return other.info == self.info else: return equal def translate(self, map): # By using r-string we don't have to escape backslashes r""" Turn this exception into another one based on regular expressions :param map: Mapping of regular expression strings to target exception instances Each regular expression is matched aagainst the error message of the instance (i.e. ``str(self)``). The corresponding target exception of the first matching regular expression is returned. >>> RPCError("foo is bad").translate({ >>> r"^foo": ValueError("Foo is something"), >>> r"is bad$": TypeError("Something is bad"), >>> }) ValueError('bad: Foo') If there are no matches, the instance (``self``) is returned. >>> RPCError("foo is bad").translate({ >>> r"Hello?": ValueError("Anybody out there?"), >>> }) RPCError("foo is bad") If the matching target exception is a ``(exception_class, message)`` tuple, any group references in ``message`` are substituted with the groups from the matching regular expression and ``exception_class(message_with_group_substitutions)`` is returned. >>> for e in (RPCError("foo is bad"), RPCError("bar is good"), RPCError("baz is silly")): >>> e.translate({ >>> r"^(\w+) is (\w+)$": (ValueError, r"\2: \1"), >>> }) ValueError('bad: foo') ValueError('good: bar') ValueError('silly: baz') Keyword arguments are also supported: >>> for e in (RPCError("foo is bad"), RPCError("bar is good"), RPCError("baz is silly")): >>> e.translate({ >>> r"^(\w+) is (\w+)$": (SomeError, r"\1", kwarg=r"\2"), >>> }) SomeError('foo', kwarg='bad') SomeError('bar', kwarg='good') SomeError('baz', kwarg='silly') """ self_msg = str(self) for regex, to_exc in map.items(): match = re.search(regex, self_msg) if match: if isinstance(to_exc, tuple) and len(to_exc) >= 2: # Split `to_exc` into exception class and its arguments with # group references to_cls, *to_args = to_exc # Split `to_args` into positional and keyword arguments to_posargs = tuple( match.expand(arg) # Replace group references (\1, \g<1>, \g<name>) for arg in to_args if not isinstance(arg, tuple) ) to_kwargs = { k: match.expand(v) # Replace group references (\1, \g<1>, \g<name>) for k, v in (a for a in to_args if isinstance(a, tuple)) } return to_cls(*to_posargs, **to_kwargs) else: return to_exc return self
[docs] class ConnectionError(Error): """Failed to connect to the client, e.g. because it isn't running""" def __init__(self, msg): # python_socks.ProxyConnectionError provides ugly errors messages, # e.g. "Could not connect to proxy localhost:1337 [None]". msg = re.sub(r'\s+\[.*?\]$', '', str(msg)) super().__init__(msg)
[docs] class TimeoutError(Error, TimeoutError): """ Timeout for sending request and reading response Besides :class:`Error`, this is also a subclass of the builtin :class:`~exceptions.TimeoutError`. """
[docs] class AuthenticationError(Error): """Failed to prove identity"""
[docs] class ValueError(Error, ValueError): """ Invalid value (e.g. port 65536) Besides :class:`Error`, this is also a subclass of the builtin :class:`~exceptions.ValueError`. """