from ircplom.events import (
AffectiveEvent, CrashingException, ExceptionEvent, QueueMixin)
from ircplom.irc_conn import (
- BaseIrcConnection, IrcConnAbortException, IrcConnException,
- IrcConnTimeoutException, IrcMessage, ILLEGAL_NICK_CHARS,
- ILLEGAL_NICK_FIRSTCHARS, ISUPPORT_DEFAULTS, PORT_SSL)
+ BaseIrcConnection, IrcConnException, IrcMessage, ERR_STR_TIMEOUT,
+ ILLEGAL_NICK_CHARS, ILLEGAL_NICK_FIRSTCHARS, ISUPPORT_DEFAULTS, PORT_SSL)
from ircplom.msg_parse_expectations import MSG_EXPECTATIONS
def _on_connecting_exception(self, e: IrcConnException) -> None:
self.db.connection_state = f'failed to connect: {e}'
- if isinstance(e, IrcConnTimeoutException):
+ if e.retry:
if not self._retry_connect_in_s > 0:
self._retry_connect_in_s = 1
self._delayed_retry_connect()
self._delayed_retry_connect()
def on_handled_loop_exception(self, e: IrcConnException) -> None:
- 'On …AbortException, call .close(), on …Timeout… first (!) try PING.'
- if isinstance(e, IrcConnAbortException):
- self._retry_connect_in_s = 1
+ 'Execute e.abort, .retry, or interpret str(e) to PING/check on PONG.'
+ if e.abort:
+ if e.retry:
+ self._retry_connect_in_s = 1
self.db.connection_state = f'broken: {e}'
self.close()
- elif isinstance(e, IrcConnTimeoutException):
+ elif str(e) == ERR_STR_TIMEOUT:
if self._expected_pong:
self.on_handled_loop_exception(
- IrcConnAbortException('no timely PONG from server'))
+ IrcConnException('no timely PONG from server',
+ abort=True, retry=True))
else:
self._expected_pong = "what's up?"
self.send('PING', self._expected_pong)
- else:
- raise e
@abstractmethod
def _on_update(self, *path) -> None:
_TIMEOUT_CONNECT = 5
_CONN_RECV_BUFSIZE = 1024
+ERR_STR_TIMEOUT = 'timeout'
+
ILLEGAL_NICK_CHARS = ' ,*?!@'
ILLEGAL_NICK_FIRSTCHARS = ':$'
ISUPPORT_DEFAULTS = {
return self._raw
-class IrcConnException(BaseException):
+class IrcConnException(Exception):
'Thrown by BaseIrcConnection on expectable connection issues.'
+ def __init__(self, *args, abort=True, retry=False, **kwargs) -> None:
+ super().__init__(*args, **kwargs)
+ self.abort = abort
+ self.retry = retry
-class IrcConnAbortException(IrcConnException):
- 'Thrown by BaseIrcConnection on expectable connection failures.'
-
-
-class IrcConnTimeoutException(IrcConnException):
- 'Thrown by BaseIrcConnection if recv timeout triggered.'
+ def __str__(self) -> str:
+ return str(self.__cause__) if not self.args else ' '.join(self.args)
class BaseIrcConnection(QueueMixin, ABC):
try:
self._socket.connect((hostname, port))
except TimeoutError as e:
- raise IrcConnTimeoutException(e) from e
+ raise IrcConnException(retry=True) from e
except socket_gaierror as e:
- raise IrcConnAbortException(e) from e
+ raise IrcConnException() from e
self._socket.settimeout(_TIMEOUT_RECV_LOOP)
def close(self) -> None:
while True:
try:
bytes_new = self._socket.recv(_CONN_RECV_BUFSIZE)
- except TimeoutError as e:
+ except TimeoutError:
if (datetime.now() - time_last_ping_check).seconds\
> _TIMEOUT_PING:
time_last_ping_check = datetime.now()
yield self._on_handled_loop_exception(
- IrcConnTimeoutException(e))
+ IrcConnException(ERR_STR_TIMEOUT, abort=False))
else:
yield None
continue
except ConnectionResetError as e:
- raise IrcConnAbortException(e) from e
+ raise IrcConnException(retry=True) from e
except OSError as e:
if e.errno == 9:
- raise IrcConnAbortException(e) from e
+ raise IrcConnException(retry=True) from e
raise e
if not bytes_new:
break
from ircplom.events import Event, Loop, QueueMixin
from ircplom.client import IrcConnection, IrcConnSetup
from ircplom.client_tui import ClientKnowingTui, ClientTui, LOG_PREFIX_IN
-from ircplom.irc_conn import (IrcConnAbortException, IrcConnTimeoutException,
- IrcMessage)
+from ircplom.irc_conn import ERR_STR_TIMEOUT, IrcConnException, IrcMessage
from ircplom.tui_base import (TerminalInterface, TuiEvent,
LOG_FMT_SEP, LOG_FMT_ATTRS)
def _set_up_socket(self, hostname: str, port: int) -> None:
if port > _FAKE_TIMEOUT_PORTS_BEYOND:
- raise IrcConnTimeoutException('FAKE TESTING TIMEOUT')
+ raise IrcConnException('FAKE TESTING TIMEOUT', retry=True)
def close(self) -> None:
self._recv_loop.stop()
continue
if msg == 'FAKE_IRC_CONN_TIMEOUT_EXCEPTION':
yield self._on_handled_loop_exception(
- IrcConnTimeoutException(msg))
+ IrcConnException(ERR_STR_TIMEOUT, abort=False))
continue
if msg == 'FAKE_IRC_CONN_ABORT_EXCEPTION':
- raise IrcConnAbortException(msg)
+ raise IrcConnException(msg, retry=True)
yield self._make_recv_event(IrcMessage.from_raw(msg))
- except IrcConnAbortException as e:
+ except IrcConnException as e:
yield self._on_handled_loop_exception(e)