shizmob / pydle

An IRCv3-compliant Python 3 IRC library.
BSD 3-Clause "New" or "Revised" License
154 stars 48 forks source link

Handle ConnectionResetError when sending PING #129

Closed hogklint closed 4 years ago

hogklint commented 4 years ago

Handle this exception in exception.

IRC:...      >> Receive timeout reached, sending ping to check connection state...
IRC:...      >> PING ...
asyncio      Task exception was never retrieved
future: <Task finished name='Task-191' coro=<BasicClient.handle_forever() done, defined at /home/.../.local/lib/python3.8/site-packages/pydle/client.py:363> exception=ConnectionResetError(104, 'Connection reset by peer')>
Traceback (most recent call last):
  File "/home/.../.local/lib/python3.8/site-packages/pydle/client.py", line 367, in handle_forever
    data = await self.connection.recv(timeout=self.READ_TIMEOUT)
  File "/home/.../.local/lib/python3.8/site-packages/pydle/connection.py", line 131, in recv
    return await asyncio.wait_for(self.reader.readline(), timeout=timeout)
  File "/usr/lib/python3.8/asyncio/tasks.py", line 490, in wait_for
    raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/.../.local/lib/python3.8/site-packages/pydle/client.py", line 374, in handle_forever
    data = await self.connection.recv(timeout=self.READ_TIMEOUT)
  File "/home/.../.local/lib/python3.8/site-packages/pydle/connection.py", line 131, in recv
    return await asyncio.wait_for(self.reader.readline(), timeout=timeout)
  File "/usr/lib/python3.8/asyncio/tasks.py", line 483, in wait_for
    return fut.result()
  File "/usr/lib/python3.8/asyncio/streams.py", line 557, in readline
    line = await self.readuntil(sep)
  File "/usr/lib/python3.8/asyncio/streams.py", line 649, in readuntil
    await self._wait_for_data('readuntil')
  File "/usr/lib/python3.8/asyncio/streams.py", line 534, in _wait_for_data
    await self._waiter
  File "/usr/lib/python3.8/asyncio/selector_events.py", line 836, in _read_ready__data_received
    data = self._sock.recv(self.max_size)
ConnectionResetError: [Errno 104] Connection reset by peer

It can be reproduced by the loss and return of server connection.

  1. Connect to IRC server
  2. Insert iptables rule rejecting all incoming and outgoing packets to server
  3. Wait for client timeout i.e. "Receive timeout reached, sending ping to check connection state..."
  4. Wait for server timing out client. Do this by having a second client in the same IRC channel as pydle.
  5. Remove rules inserted in 2.
  6. Wait for ConnectionResetError.
theunkn0wn1 commented 4 years ago

Thanks For your Contribution!

This PR makes sense, network connections can be a tad temperamental at times.

I would like to merge this into develop first, so I can merge it into master once ready for the next release (i have a couple outstanding tickets il be seeing to in the next week or two).

Can you please rebase against develop?

hogklint commented 4 years ago

Yeah sure. Done.

theunkn0wn1 commented 4 years ago

Thanks.