From 97b5ec9c97d3b6fdfa46b9f246bffbbad5e518ca Mon Sep 17 00:00:00 2001 From: alok-108 Date: Tue, 27 Oct 2026 02:40:07 +0530 Subject: [PATCH] fix: dispatch close before raising event listener error (#3293) --- playwright/_impl/connection.py | 12 ++++++++---- tests/common/test_events.py | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/playwright/_impl/connection.py b/playwright/_impl/connection.py index 6c387f940..0b01ac813 100644 --- a/playwright/_impl/connection.py +++ b/playwright/_impl/connection.py @@ -217,7 +217,7 @@ def send_message_to_server( ) # Python: the next API call raises the error of an event listener, as the # Python client always has; an unhandled rejection crashes Node.js. - if self._error and method != "__waitInfo__": + if self._error and method not in ("__waitInfo__", "close", "dispose"): error = self._error self._error = None raise error @@ -335,9 +335,13 @@ def dispatch(self, message: Dict[str, Any]) -> None: callback.reject(parsed_error) else: validator = find_validator(callback.type, callback.method, "Result") - callback.resolve( - validator(result, "", self._validator_from_wire_context()) - ) + res = validator(result, "", self._validator_from_wire_context()) + if self._error and callback.method == "close": + error = self._error + self._error = None + callback.reject(error) + else: + callback.resolve(res) return if debug_logger.is_enabled("channel"): diff --git a/tests/common/test_events.py b/tests/common/test_events.py index 07d6c4e2b..554069628 100644 --- a/tests/common/test_events.py +++ b/tests/common/test_events.py @@ -30,3 +30,21 @@ def fail() -> None: with browser.new_page() as page: page.on("response", lambda _: fail()) page.goto(server.PREFIX + "/grid.html") + + +def test_event_error_does_not_prevent_browser_close( + browser_name: str, launch_arguments: Dict, server: Server +) -> None: + with sync_playwright() as p: + browser = p[browser_name].launch(**launch_arguments) + try: + page = browser.new_page() + page.on("response", lambda _: (_ for _ in ()).throw(ValueError("listener error"))) + page.goto(server.PREFIX + "/grid.html") + finally: + try: + browser.close() + except ValueError: + pass + assert not browser.is_connected() +