Skip to content

Commit

Permalink
Review AndroidTV decorator exception management (#114133)
Browse files Browse the repository at this point in the history
  • Loading branch information
ollo69 committed May 6, 2024
1 parent 8e66e5b commit 5db8082
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 18 deletions.
31 changes: 21 additions & 10 deletions homeassistant/components/androidtv/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,22 +77,33 @@ async def _adb_exception_catcher(
)
return None
except self.exceptions as err:
_LOGGER.error(
(
"Failed to execute an ADB command. ADB connection re-"
"establishing attempt in the next update. Error: %s"
),
err,
)
if self.available:
_LOGGER.error(
(
"Failed to execute an ADB command. ADB connection re-"
"establishing attempt in the next update. Error: %s"
),
err,
)

await self.aftv.adb_close()
self._attr_available = False
return None
except Exception:
except Exception as err: # pylint: disable=broad-except
# 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()
self._attr_available = False
raise
return None

return _adb_exception_catcher

Expand Down
26 changes: 18 additions & 8 deletions tests/components/androidtv/test_media_player.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""The tests for the androidtv platform."""

from collections.abc import Generator
from datetime import timedelta
import logging
from typing import Any
Expand Down Expand Up @@ -170,7 +171,7 @@


@pytest.fixture(autouse=True)
def adb_device_tcp_fixture() -> None:
def adb_device_tcp_fixture() -> Generator[None, patchers.AdbDeviceTcpAsyncFake, None]:
"""Patch ADB Device TCP."""
with patch(
"androidtv.adb_manager.adb_manager_async.AdbDeviceTcpAsync",
Expand All @@ -180,7 +181,7 @@ def adb_device_tcp_fixture() -> None:


@pytest.fixture(autouse=True)
def load_adbkey_fixture() -> None:
def load_adbkey_fixture() -> Generator[None, str, None]:
"""Patch load_adbkey."""
with patch(
"homeassistant.components.androidtv.ADBPythonSync.load_adbkey",
Expand All @@ -190,7 +191,7 @@ def load_adbkey_fixture() -> None:


@pytest.fixture(autouse=True)
def keygen_fixture() -> None:
def keygen_fixture() -> Generator[None, Mock, None]:
"""Patch keygen."""
with patch(
"homeassistant.components.androidtv.keygen",
Expand Down Expand Up @@ -1181,7 +1182,7 @@ async def test_connection_closed_on_ha_stop(hass: HomeAssistant) -> None:
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.
HA will attempt to reconnect on the next update.
Expand All @@ -1201,12 +1202,21 @@ async def test_exception(hass: HomeAssistant) -> None:
assert state is not None
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
with patchers.PATCH_ANDROIDTV_UPDATE_EXCEPTION, pytest.raises(Exception):
with patchers.PATCH_ANDROIDTV_UPDATE_EXCEPTION:
await async_update_entity(hass, entity_id)
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_UNAVAILABLE

state = hass.states.get(entity_id)
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
await async_update_entity(hass, entity_id)
Expand Down

0 comments on commit 5db8082

Please sign in to comment.