Fix swallowed exceptions in pi_hole action handlers (#181574)

This commit is contained in:
Abdellatif Anaflous
2026-09-08 07:34:06 +02:00
committed by GitHub
parent 8ba416558a
commit 178ab42316
3 changed files with 44 additions and 23 deletions
@@ -94,6 +94,14 @@
}
}
},
"exceptions": {
"disable_failed": {
"message": "Failed to disable Pi-hole: {error}"
},
"enable_failed": {
"message": "Failed to enable Pi-hole: {error}"
}
},
"issues": {
"v5_to_v6_migration": {
"description": "You've likely updated your Pi-hole to API v6 from v5. Some sensors changed in the new API, the daily sensors were removed, and your old API token is invalid. Provide your new app password by re-authenticating in repairs or in **Settings -> Devices & services -> Pi-hole**.",
+12 -5
View File
@@ -8,10 +8,11 @@ import voluptuous as vol
from homeassistant.components.switch import SwitchEntity
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import SERVICE_DISABLE, SERVICE_DISABLE_ATTR_DURATION
from .const import DOMAIN, SERVICE_DISABLE, SERVICE_DISABLE_ATTR_DURATION
from .coordinator import PiHoleConfigEntry
from .entity import PiHoleEntity
@@ -78,9 +79,12 @@ class PiHoleSwitch(PiHoleEntity, SwitchEntity):
try:
await self.api.enable()
await self.async_update()
# pylint: disable-next=home-assistant-action-swallowed-exception
except HoleError as err:
_LOGGER.error("Unable to enable Pi-hole: %s", err)
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="enable_failed",
translation_placeholders={"error": str(err)},
) from err
@override
async def async_turn_off(self, **kwargs: Any) -> None:
@@ -101,6 +105,9 @@ class PiHoleSwitch(PiHoleEntity, SwitchEntity):
try:
await self.api.disable(duration_seconds)
await self.async_update()
# pylint: disable-next=home-assistant-action-swallowed-exception
except HoleError as err:
_LOGGER.error("Unable to disable Pi-hole: %s", err)
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="disable_failed",
translation_placeholders={"error": str(err)},
) from err
+24 -18
View File
@@ -1,6 +1,5 @@
"""Test pi_hole component."""
import logging
from unittest.mock import ANY, AsyncMock
from hole.exceptions import HoleError
@@ -23,6 +22,7 @@ from homeassistant.const import (
CONF_SSL,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from . import (
API_KEY,
@@ -289,7 +289,7 @@ async def test_setup_name_from_entry_title(hass: HomeAssistant) -> None:
assert hass.states.get("sensor.my_hole_ads_blocked").name == "My Hole Ads blocked"
async def test_switch(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) -> None:
async def test_switch(hass: HomeAssistant) -> None:
"""Test Pi-hole switch."""
mocked_hole = _create_mocked_hole()
entry = MockConfigEntry(
@@ -322,23 +322,29 @@ async def test_switch(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) ->
# Failed calls
mocked_hole.instances[-1].enable = AsyncMock(side_effect=HoleError("Error1"))
await hass.services.async_call(
switch.DOMAIN,
switch.SERVICE_TURN_ON,
{"entity_id": SWITCH_ENTITY_ID},
blocking=True,
)
mocked_hole.instances[-1].disable = AsyncMock(side_effect=HoleError("Error2"))
await hass.services.async_call(
switch.DOMAIN,
switch.SERVICE_TURN_OFF,
{"entity_id": SWITCH_ENTITY_ID},
blocking=True,
)
errors = [x for x in caplog.records if x.levelno == logging.ERROR]
with pytest.raises(HomeAssistantError) as enable_error:
await hass.services.async_call(
switch.DOMAIN,
switch.SERVICE_TURN_ON,
{"entity_id": SWITCH_ENTITY_ID},
blocking=True,
)
assert errors[-2].message == "Unable to enable Pi-hole: Error1"
assert errors[-1].message == "Unable to disable Pi-hole: Error2"
mocked_hole.instances[-1].disable = AsyncMock(side_effect=HoleError("Error2"))
with pytest.raises(HomeAssistantError) as disable_error:
await hass.services.async_call(
switch.DOMAIN,
switch.SERVICE_TURN_OFF,
{"entity_id": SWITCH_ENTITY_ID},
blocking=True,
)
assert enable_error.value.translation_domain == pi_hole.DOMAIN
assert enable_error.value.translation_key == "enable_failed"
assert enable_error.value.translation_placeholders == {"error": "Error1"}
assert disable_error.value.translation_domain == pi_hole.DOMAIN
assert disable_error.value.translation_key == "disable_failed"
assert disable_error.value.translation_placeholders == {"error": "Error2"}
async def test_disable_service_call(hass: HomeAssistant) -> None: