Review AndroidTV decorator exception management (#114133)

This commit is contained in:
ollo69 2024-05-07 01:00:12 +02:00 committed by GitHub
parent 8e66e5bb11
commit 5db8082f91
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 18 deletions

View file

@ -77,22 +77,33 @@ def adb_decorator(
) )
return None return None
except self.exceptions as err: except self.exceptions as err:
_LOGGER.error( if self.available:
( _LOGGER.error(
"Failed to execute an ADB command. ADB connection re-" (
"establishing attempt in the next update. Error: %s" "Failed to execute an ADB command. ADB connection re-"
), "establishing attempt in the next update. Error: %s"
err, ),
) err,
)
await self.aftv.adb_close() await self.aftv.adb_close()
self._attr_available = False self._attr_available = False
return None return None
except Exception: except Exception as err: # pylint: disable=broad-except
# An unforeseen exception occurred. Close the ADB connection so that # An unforeseen exception occurred. Close the ADB connection so that
# it doesn't happen over and over again, then raise the exception. # it doesn't happen over and over again.
if self.available:
_LOGGER.error(
(
"Unexpected exception executing an ADB command. ADB connection"
" re-establishing attempt in the next update. Error: %s"
),
err,
)
await self.aftv.adb_close() await self.aftv.adb_close()
self._attr_available = False self._attr_available = False
raise return None
return _adb_exception_catcher return _adb_exception_catcher

View file

@ -1,5 +1,6 @@
"""The tests for the androidtv platform.""" """The tests for the androidtv platform."""
from collections.abc import Generator
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import Any from typing import Any
@ -170,7 +171,7 @@ CONFIG_FIRETV_DEFAULT = CONFIG_FIRETV_PYTHON_ADB
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def adb_device_tcp_fixture() -> None: def adb_device_tcp_fixture() -> Generator[None, patchers.AdbDeviceTcpAsyncFake, None]:
"""Patch ADB Device TCP.""" """Patch ADB Device TCP."""
with patch( with patch(
"androidtv.adb_manager.adb_manager_async.AdbDeviceTcpAsync", "androidtv.adb_manager.adb_manager_async.AdbDeviceTcpAsync",
@ -180,7 +181,7 @@ def adb_device_tcp_fixture() -> None:
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def load_adbkey_fixture() -> None: def load_adbkey_fixture() -> Generator[None, str, None]:
"""Patch load_adbkey.""" """Patch load_adbkey."""
with patch( with patch(
"homeassistant.components.androidtv.ADBPythonSync.load_adbkey", "homeassistant.components.androidtv.ADBPythonSync.load_adbkey",
@ -190,7 +191,7 @@ def load_adbkey_fixture() -> None:
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def keygen_fixture() -> None: def keygen_fixture() -> Generator[None, Mock, None]:
"""Patch keygen.""" """Patch keygen."""
with patch( with patch(
"homeassistant.components.androidtv.keygen", "homeassistant.components.androidtv.keygen",
@ -1181,7 +1182,7 @@ async def test_connection_closed_on_ha_stop(hass: HomeAssistant) -> None:
assert adb_close.called assert adb_close.called
async def test_exception(hass: HomeAssistant) -> None: async def test_exception(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) -> None:
"""Test that the ADB connection gets closed when there is an unforeseen exception. """Test that the ADB connection gets closed when there is an unforeseen exception.
HA will attempt to reconnect on the next update. HA will attempt to reconnect on the next update.
@ -1201,12 +1202,21 @@ async def test_exception(hass: HomeAssistant) -> None:
assert state is not None assert state is not None
assert state.state == STATE_OFF assert state.state == STATE_OFF
caplog.clear()
caplog.set_level(logging.ERROR)
# When an unforeseen exception occurs, we close the ADB connection and raise the exception # When an unforeseen exception occurs, we close the ADB connection and raise the exception
with patchers.PATCH_ANDROIDTV_UPDATE_EXCEPTION, pytest.raises(Exception): with patchers.PATCH_ANDROIDTV_UPDATE_EXCEPTION:
await async_update_entity(hass, entity_id) await async_update_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state is not None state = hass.states.get(entity_id)
assert state.state == STATE_UNAVAILABLE assert state is not None
assert state.state == STATE_UNAVAILABLE
assert len(caplog.record_tuples) == 1
assert caplog.record_tuples[0][1] == logging.ERROR
assert caplog.record_tuples[0][2].startswith(
"Unexpected exception executing an ADB command"
)
# On the next update, HA will reconnect to the device # On the next update, HA will reconnect to the device
await async_update_entity(hass, entity_id) await async_update_entity(hass, entity_id)