diff --git a/homeassistant/components/bluetooth/__init__.py b/homeassistant/components/bluetooth/__init__.py index fb514a33e99..9266603839c 100644 --- a/homeassistant/components/bluetooth/__init__.py +++ b/homeassistant/components/bluetooth/__init__.py @@ -440,5 +440,11 @@ class BluetoothManager: self._cancel_unavailable_tracking() self._cancel_unavailable_tracking = None if self.scanner: - await self.scanner.stop() + try: + await self.scanner.stop() + except BleakError as ex: + # This is not fatal, and they may want to reload + # the config entry to restart the scanner if they + # change the bluetooth dongle. + _LOGGER.error("Error stopping scanner: %s", ex) uninstall_multiple_bleak_catcher() diff --git a/tests/components/bluetooth/test_init.py b/tests/components/bluetooth/test_init.py index 8b0d60bc42d..aa3a6253b83 100644 --- a/tests/components/bluetooth/test_init.py +++ b/tests/components/bluetooth/test_init.py @@ -1213,3 +1213,20 @@ async def test_getting_the_scanner_returns_the_wrapped_instance(hass, enable_blu """Test getting the scanner returns the wrapped instance.""" scanner = bluetooth.async_get_scanner(hass) assert isinstance(scanner, models.HaBleakScannerWrapper) + + +async def test_config_entry_can_be_reloaded_when_stop_raises( + hass, caplog, enable_bluetooth +): + """Test we can reload if stopping the scanner raises.""" + entry = hass.config_entries.async_entries(bluetooth.DOMAIN)[0] + assert entry.state == ConfigEntryState.LOADED + + with patch( + "homeassistant.components.bluetooth.HaBleakScanner.stop", side_effect=BleakError + ): + await hass.config_entries.async_reload(entry.entry_id) + await hass.async_block_till_done() + + assert entry.state == ConfigEntryState.LOADED + assert "Error stopping scanner" in caplog.text