Skip to content

Commit

Permalink
fix: clear exception flag on disconnect future if its also sent to ha…
Browse files Browse the repository at this point in the history
…ndlers (#281)
  • Loading branch information
bdraco authored May 20, 2024
1 parent f73e13e commit be68a79
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/dbus_fast/aio/message_bus.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import array
import asyncio
import contextlib
import logging
import socket
from collections import deque
Expand Down Expand Up @@ -522,13 +523,23 @@ def _finalize(self, err: Optional[Exception] = None) -> None:
except Exception:
logging.warning("could not remove message writer", exc_info=True)

had_handlers = bool(self._method_return_handlers or self._user_message_handlers)

super()._finalize(err)

if self._disconnect_future.done():
return

if err and not self._user_disconnect:
_future_set_exception(self._disconnect_future, err)
# If this happens during a reply, the message handlers
# will have the exception set and wait_for_disconnect will
# never be called so we need to manually set the exception
# as retrieved to avoid asyncio warnings when the future
# is garbage collected.
if had_handlers:
with contextlib.suppress(Exception):
self._disconnect_future.exception()
else:
_future_set_result(self._disconnect_future, None)

Expand Down
19 changes: 19 additions & 0 deletions tests/test_aio_low_level.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,25 @@ async def test_standard_interfaces():
bus.disconnect()


@pytest.mark.asyncio
async def test_error_handling():
bus = await MessageBus().connect()
msg = Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="InvalidMember",
serial=bus.next_serial(),
)
reply = await bus.call(msg)

assert reply.message_type == MessageType.ERROR
assert reply.reply_serial == msg.serial
assert reply.signature == "s"

bus.disconnect()


@pytest.mark.asyncio
async def test_sending_messages_between_buses():
bus1 = await MessageBus().connect()
Expand Down

0 comments on commit be68a79

Please sign in to comment.