altdesktop / python-dbus-next

🚌 The next great DBus library for Python with asyncio support
https://python-dbus-next.readthedocs.io/en/latest/
MIT License
187 stars 59 forks source link

Ensure future is not done when setting exception #73

Closed hetelek closed 3 years ago

hetelek commented 3 years ago

This is needed to properly handle asyncio timeouts. If the future is already done, then set_exception will raise an exception and the self.bus._finalize call will not be reached.

I ran into this failure mode when wrapping bus.call in asyncio.wait_for: await asyncio.wait_for(bus.call(...), timeout=10)

If the timeout was reached, it would cause an infinite loop of errors:

Traceback (most recent call last):
  File "asyncio/events.py", line 127, in _run
  File "site-packages/dbus_next/aio/message_bus.py", line 63, in write_callback
asyncio.base_futures.InvalidStateError: invalid state
2020-11-25 12:05:01,578 - asyncio - ERROR - Exception in callback _MessageWriter.write_callback()
handle: <Handle _MessageWriter.write_callback()>
Traceback (most recent call last):
  File "site-packages/dbus_next/aio/message_bus.py", line 51, in write_callback
BrokenPipeError: [Errno 32] Broken pipe

During handling of the above exception, another exception occurred:

...
acrisci commented 3 years ago

:+1: