@@ -1661,6 +1661,47 @@ def on_bluetooth_gatt_notify(handle: int, data: bytearray) -> None:
1661
1661
)
1662
1662
1663
1663
1664
+ async def test_bluetooth_gatt_notify_callback_raises (
1665
+ api_client : tuple [
1666
+ APIClient , APIConnection , asyncio .Transport , APIPlaintextFrameHelper
1667
+ ],
1668
+ caplog : pytest .LogCaptureFixture ,
1669
+ ) -> None :
1670
+ """Test that exceptions in bluetooth gatt notify callbacks are caught."""
1671
+ client , connection , transport , protocol = api_client
1672
+
1673
+ def on_bluetooth_gatt_notify (handle : int , data : bytearray ) -> None :
1674
+ raise ValueError ("Test exception in notify callback" )
1675
+
1676
+ notify_task = asyncio .create_task (
1677
+ client .bluetooth_gatt_start_notify (1234 , 1 , on_bluetooth_gatt_notify )
1678
+ )
1679
+ await asyncio .sleep (0 )
1680
+ notify_response : message .Message = BluetoothGATTNotifyResponse (
1681
+ address = 1234 , handle = 1
1682
+ )
1683
+ mock_data_received (protocol , generate_plaintext_packet (notify_response ))
1684
+ await notify_task
1685
+
1686
+ # Clear any logs from the notify setup
1687
+ caplog .clear ()
1688
+
1689
+ # Send data that will trigger the exception
1690
+ data_response : message .Message = BluetoothGATTNotifyDataResponse (
1691
+ address = 1234 , handle = 1 , data = b"test_data"
1692
+ )
1693
+ mock_data_received (protocol , generate_plaintext_packet (data_response ))
1694
+ await asyncio .sleep (0 )
1695
+
1696
+ # Verify the exception was caught and logged
1697
+ assert "Unexpected error in Bluetooth GATT notify callback" in caplog .text
1698
+ assert "ValueError: Test exception in notify callback" in caplog .text
1699
+ assert "address 1234, handle 1" in caplog .text
1700
+
1701
+ # Verify the connection is still alive
1702
+ assert connection .is_connected
1703
+
1704
+
1664
1705
async def test_subscribe_bluetooth_le_advertisements (
1665
1706
api_client : tuple [
1666
1707
APIClient , APIConnection , asyncio .Transport , APIPlaintextFrameHelper
0 commit comments