Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle exceptions in the sending callback #12

Merged

Conversation

nARN
Copy link

@nARN nARN commented Apr 23, 2019

socket.sendto can raise some exceptions in which case the callback is repeatedly called as the socket remains writable and the callback stays registered. The exception is simply printed and does not propagate. Thus permanent exceptions effectively cause an infinite loop.

One example is trying to ping local network's broadcast or network addresses:
The local machine is on 192.168.192.0/30

>>> import asyncio
>>> import aioping
>>>
>>> async def do_ping(host):
...     try:
...         delay = await aioping.ping(host) * 1000
...         print("Ping response in %s ms" % delay)
...     except TimeoutError:
...         print("Timed out")
... 
>>> loop = asyncio.get_event_loop()
>>> loop.run_until_complete(do_ping("192.168.192.1"))
Ping response in 0.37360191345214844 ms
>>>
>>> loop.run_until_complete(do_ping("192.168.192.0"))
Exception in callback sendto_ready(packet=b'\x08\x00\xd...QQQQQQQQQQQQQ', socket=<socket.socke...'0.0.0.0', 1)>, dest=('192.168.192.0', 0), future=<Future pendi...757f35c48>()]>)() at /home/narn/repos/aioping/aioping/__init__.py:179
handle: <Handle sendto_ready(packet=b'\x08\x00\xd...QQQQQQQQQQQQQ', socket=<socket.socke...'0.0.0.0', 1)>, dest=('192.168.192.0', 0), future=<Future pendi...757f35c48>()]>)() at /home/narn/repos/aioping/aioping/__init__.py:179>
Traceback (most recent call last):
  File "/usr/lib/python3.6/asyncio/events.py", line 145, in _run
    self._callback(*self._args)
  File "/home/narn/repos/aioping/aioping/__init__.py", line 180, in sendto_ready
    socket.sendto(packet, dest)
PermissionError: [Errno 13] Permission denied
...
...
...
Exception in callback sendto_ready(packet=b'\x08\x00\xd...QQQQQQQQQQQQQ', socket=<socket.socke...'0.0.0.0', 1)>, dest=('192.168.192.0', 0), future=<Future pendi...757f35c48>()]>)() at /home/narn/repos/aioping/aioping/__init__.py:179
handle: <Handle sendto_ready(packet=b'\x08\x00\xd...QQQQQQQQQQQQQ', socket=<socket.socke...'0.0.0.0', 1)>, dest=('192.168.192.0', 0), future=<Future pendi...757f35c48>()]>)() at /home/narn/repos/aioping/aioping/__init__.py:179>
Traceback (most recent call last):
  File "/usr/lib/python3.6/asyncio/events.py", line 145, in _run
    self._callback(*self._args)
  File "/home/narn/repos/aioping/aioping/__init__.py", line 180, in sendto_ready
    socket.sendto(packet, dest)
PermissionError: [Errno 13] Permission denied
...
...
...

I could think of two exceptions that should be retried.

  • BlockingIOError. Strictly speaking it should not happen in these circumstances, but I could not find any guarantee in the docs.
  • InterruptedError should no longer appear in python 3.5 as it now retries syscalls instead of raising it, however I assumed this library could work on py3.4 and kept it.

All other exceptions should likely be propagated to the caller.

After these changes (again, the machine is on 192.168.192.0/30):

>>> import asyncio
>>> import aioping
>>>
>>> async def do_ping(host):
...     try:
...         delay = await aioping.ping(host) * 1000
...         print("Ping response in %s ms" % delay)
...     except TimeoutError:
...         print("Timed out")
... 
>>> loop = asyncio.get_event_loop()
>>> loop.run_until_complete(do_ping("192.168.192.1"))
Ping response in 0.23651123046875 ms
>>>
>>> loop.run_until_complete(do_ping("192.168.192.0"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
    return future.result()
  File "<stdin>", line 3, in do_ping
  File "/home/narn/repos/aioping/aioping/__init__.py", line 270, in ping
    await send_one_ping(my_socket, addr, my_id, timeout, family)
  File "/home/narn/repos/aioping/aioping/__init__.py", line 228, in send_one_ping
    await future
  File "/home/narn/repos/aioping/aioping/__init__.py", line 181, in sendto_ready
    socket.sendto(packet, dest)
PermissionError: [Errno 13] Permission denied
>>>

@kevchentw
Copy link

This PR fixes my problem using aioping.

@anton-belousov anton-belousov changed the base branch from master to pr-12-exceptions-in-callback July 4, 2020 14:27
@anton-belousov anton-belousov merged commit 3bb4dec into stellarbit:pr-12-exceptions-in-callback Jul 4, 2020
Crypto-Spartan pushed a commit to Crypto-Spartan/aioping that referenced this pull request Oct 30, 2020
Handle exceptions in the sending callback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants