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: