From fcd721a963f5eab4322f57a279853274c15348fb Mon Sep 17 00:00:00 2001 From: zigpy-review-bot <286747149+zigpy-review-bot@users.noreply.github.com> Date: Wed, 28 Oct 2026 23:43:26 +0100 Subject: [PATCH] Fail cleanly when sending while disconnected A request that is still queued when the radio disconnects, e.g. a reply to a device after startup has failed, called `aps_data_request` on `None` and logged an `AttributeError` traceback. Raise a `DeliveryError` instead, like any other failed send. --- tests/test_send_receive.py | 11 +++++++++++ zigpy_deconz/zigbee/application.py | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/tests/test_send_receive.py b/tests/test_send_receive.py index 2ac3298..9490a82 100644 --- a/tests/test_send_receive.py +++ b/tests/test_send_receive.py @@ -248,3 +248,14 @@ async def test_send_packet_deliver_failure(app, tx_packet): # noqa: F811 await app.send_packet(tx_packet) assert "Failed to deliver" in str(e) + + +async def test_send_packet_disconnected(app, tx_packet): # noqa: F811 + """Sending after the radio was disconnected fails cleanly.""" + app._api = None + + with pytest.raises(zigpy.exceptions.DeliveryError) as e: + await app.send_packet(tx_packet) + + assert "not connected" in str(e) + assert not app._pending_requests diff --git a/zigpy_deconz/zigbee/application.py b/zigpy_deconz/zigbee/application.py index 45d6e23..c068993 100644 --- a/zigpy_deconz/zigbee/application.py +++ b/zigpy_deconz/zigbee/application.py @@ -565,6 +565,11 @@ async def send_packet(self, packet): tx_options |= t.DeconzTransmitOptions.USE_APS_ACKS async with self._limit_concurrency(priority=packet.priority): + # The radio can be disconnected while the request waits its turn, e.g. + # when a device is replied to after startup has failed + if self._api is None: + raise zigpy.exceptions.DeliveryError("Coordinator is not connected") + req_id = self.get_sequence() if req_id in self._pending_requests: