From bdc3a1436fc6a339ba9b07453d274fd773886cbb Mon Sep 17 00:00:00 2001 From: Falko Schindler Date: Mon, 27 May 2024 10:42:54 +0200 Subject: [PATCH] Warn about communication attempts with disconnected clients (#3123) * refactoring * check existence before communicating with client * Revert "refactoring" This reverts commit bf089c28d5acc62be554f67075752ba8d216c0f9. * add stack trace --- nicegui/client.py | 11 +++++++++++ nicegui/outbox.py | 3 +++ 2 files changed, 14 insertions(+) diff --git a/nicegui/client.py b/nicegui/client.py index 1e301ffd4..ada68d69b 100644 --- a/nicegui/client.py +++ b/nicegui/client.py @@ -59,6 +59,8 @@ def __init__(self, page: page, *, shared: bool = False) -> None: self.shared = shared self.on_air = False self._disconnect_task: Optional[asyncio.Task] = None + self._deleted = False + self._has_warned_about_deleted_client = False self.tab_id: Optional[str] = None self.outbox = Outbox(self) @@ -320,6 +322,15 @@ def delete(self) -> None: self.remove_all_elements() self.outbox.stop() del Client.instances[self.id] + self._deleted = True + + def check_existence(self) -> None: + """Check if the client still exists and print a warning if it doesn't.""" + if self._deleted and not self._has_warned_about_deleted_client: + log.warning('Client has been deleted but is still being used. This is most likely a bug in your application code. ' + 'See https://github.com/zauberzeug/nicegui/issues/3028 for more information.', + stack_info=True) + self._has_warned_about_deleted_client = True @contextmanager def individual_target(self, socket_id: str) -> Iterator[None]: diff --git a/nicegui/outbox.py b/nicegui/outbox.py index 52d74095d..b65a759bf 100644 --- a/nicegui/outbox.py +++ b/nicegui/outbox.py @@ -36,16 +36,19 @@ def _set_enqueue_event(self) -> None: def enqueue_update(self, element: Element) -> None: """Enqueue an update for the given element.""" + self.client.check_existence() self.updates[element.id] = element self._set_enqueue_event() def enqueue_delete(self, element: Element) -> None: """Enqueue a deletion for the given element.""" + self.client.check_existence() self.updates[element.id] = None self._set_enqueue_event() def enqueue_message(self, message_type: MessageType, data: Any, target_id: ClientId) -> None: """Enqueue a message for the given client.""" + self.client.check_existence() self.messages.append((target_id, message_type, data)) self._set_enqueue_event()