Skip to content

Commit

Permalink
irc: properly manage exceptions in the run-forever loop
Browse files Browse the repository at this point in the history
Co-authored-by: dgw <dgw@technobabbl.es>
  • Loading branch information
Exirel and dgw committed Apr 19, 2023
1 parent c4a34f7 commit ad21253
Showing 1 changed file with 39 additions and 3 deletions.
42 changes: 39 additions & 3 deletions sopel/irc/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,9 @@ async def read_forever(self) -> None:
while not self._reader.at_eof():
try:
line: bytes = await self._reader.readuntil(separator=b'\r\n')
except asyncio.exceptions.IncompleteReadError as e:
except asyncio.exceptions.IncompleteReadError as err:
LOGGER.warning('Receiving partial message from IRC.')
line = e.partial
line = err.partial
except asyncio.exceptions.LimitOverrunError:
LOGGER.exception('Unable to read from IRC server.')
break
Expand Down Expand Up @@ -500,8 +500,25 @@ async def _run_forever(self) -> None:
self._read_task = asyncio.create_task(self.read_forever())
try:
await self._read_task

# task was cancelled, i.e. another exception is responsible for that
except asyncio.CancelledError:
LOGGER.debug('Read task was cancelled.')

# connection reset requires a log, but no exception log
except ConnectionResetError as err:
LOGGER.error('Connection reset on read: %s', err)

# generic (connection) error requires a specific exception log
except ConnectionError as err:
LOGGER.error('Connection error on read: %s', err)
self.log_exception()

except Exception as err:
LOGGER.error('Unexpected error on read: %s', err)
self.log_exception()

# task done (connection closed without error)
else:
LOGGER.debug('Reader received EOF.')

Expand All @@ -514,7 +531,26 @@ async def _run_forever(self) -> None:
# nothing to read anymore
LOGGER.debug('Shutting down writer.')
self._writer.close()
await self._writer.wait_closed()
try:
await self._writer.wait_closed()

# task was cancelled, i.e. another exception is responsible for that
except asyncio.CancelledError:
LOGGER.debug('Writer task was cancelled.')

# connection reset happened before on the read task
except ConnectionResetError as err:
LOGGER.debug('Connection reset while closing: %s', err)

# generic (connection) error requires a specific exception log
except ConnectionError as err:
LOGGER.error('Connection error while closing: %s', err)
self.log_exception()

except Exception:
LOGGER.error('Unexpected error while shutting down socket.')
self.log_exception()

LOGGER.debug('All clear, exiting now.')

def run_forever(self) -> None:
Expand Down

0 comments on commit ad21253

Please sign in to comment.