@@ -859,7 +859,7 @@ def bluetooth_scanner_set_mode(self, mode: BluetoothScannerMode) -> None:
859859 """Set the Bluetooth scanner mode."""
860860 self ._get_connection ().send_message (BluetoothScannerSetModeRequest (mode = mode ))
861861
862- async def bluetooth_device_connect ( # noqa: C901 # pylint: disable=too-many-locals, too-many-branches
862+ async def bluetooth_device_connect ( # noqa: C901 # pylint: disable=too-many-locals
863863 self ,
864864 address : int ,
865865 on_bluetooth_connection_state : Callable [[bool , int , int ], None ],
@@ -923,22 +923,16 @@ def on_bluetooth_connection_state_with_notify_cleanup(
923923 timeout_handle = loop .call_at (
924924 loop .time () + timeout , handle_timeout , connect_future
925925 )
926- timeout_expired = False
927- connect_ok = False
928- unhandled_exception = False
929926 try :
930927 await connect_future
931- connect_ok = True
932928 except TimeoutError as err :
933- # If the timeout expires, make sure
934- # to unsub before calling _bluetooth_device_disconnect_guard_timeout
935- # so that the disconnect message is not propagated back to the caller
936- # since we are going to raise a TimeoutAPIError.
929+ # Unsub before disconnecting so the disconnect message is not
930+ # propagated back to the caller — we are going to raise a
931+ # TimeoutAPIError instead.
937932 unsub ()
938- timeout_expired = True
939- # Disconnect before raising the exception to ensure
940- # the slot is recovered before the timeout is raised
941- # to avoid race were we run out even though we have a slot.
933+ # Disconnect before raising the exception so the slot is
934+ # recovered before the timeout is raised, avoiding a race
935+ # where we run out of slots even though we have one.
942936 addr = to_human_readable_address (address )
943937 if self ._debug_enabled :
944938 _LOGGER .debug ("%s: Connecting timed out, waiting for disconnect" , addr )
@@ -954,31 +948,26 @@ def on_bluetooth_connection_state_with_notify_cleanup(
954948 )
955949 raise TimeoutAPIError (msg ) from err
956950 except asyncio .CancelledError :
957- unhandled_exception = True
958- # Distinguish an outside cancellation of our task from
959- # a cancellation of the connect_future itself. If the
960- # current task is not actually being cancelled, convert
961- # the CancelledError into an APIConnectionError so that
962- # callers (and their retry logic) can handle it as a
963- # normal connection failure instead of aborting.
951+ unsub ()
952+ self ._bluetooth_disconnect_no_wait (address )
953+ # Distinguish an outside cancellation of our task from a
954+ # cancellation of the connect_future itself. If the current
955+ # task is not actually being cancelled, convert the
956+ # CancelledError into an APIConnectionError so callers (and
957+ # their retry logic) can treat it as a normal connection
958+ # failure instead of aborting.
964959 current_task = asyncio .current_task ()
965960 if current_task is None or not current_task .cancelling ():
966961 addr = to_human_readable_address (address )
967962 msg = f"Connect attempt to { addr } was cancelled"
968963 raise APIConnectionError (msg ) from None
969964 raise
970965 except BaseException :
971- unhandled_exception = True
966+ unsub ()
967+ self ._bluetooth_disconnect_no_wait (address )
972968 raise
973969 finally :
974- if unhandled_exception or (not connect_ok and not timeout_expired ):
975- unsub ()
976- if not timeout_expired :
977- timeout_handle .cancel ()
978- if unhandled_exception :
979- # Make sure to disconnect if we had an unhandled exception
980- # as otherwise the connection will be left open.
981- self ._bluetooth_disconnect_no_wait (address )
970+ timeout_handle .cancel ()
982971
983972 return unsub
984973
0 commit comments