Improve debugging and error handling in Fritz!Tools (#65324)

This commit is contained in:
Michael 2022-02-01 00:28:11 +01:00 committed by GitHub
parent 18ea3fb85a
commit c9f38355f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 20 deletions

View File

@ -1,11 +1,7 @@
"""Support for AVM Fritz!Box functions.""" """Support for AVM Fritz!Box functions."""
import logging import logging
from fritzconnection.core.exceptions import ( from fritzconnection.core.exceptions import FritzSecurityError
FritzConnectionException,
FritzResourceError,
FritzSecurityError,
)
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
@ -13,7 +9,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from .common import AvmWrapper, FritzData from .common import AvmWrapper, FritzData
from .const import DATA_FRITZ, DOMAIN, PLATFORMS from .const import DATA_FRITZ, DOMAIN, FRITZ_EXCEPTIONS, PLATFORMS
from .services import async_setup_services, async_unload_services from .services import async_setup_services, async_unload_services
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -34,7 +30,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
await avm_wrapper.async_setup(entry.options) await avm_wrapper.async_setup(entry.options)
except FritzSecurityError as ex: except FritzSecurityError as ex:
raise ConfigEntryAuthFailed from ex raise ConfigEntryAuthFailed from ex
except (FritzConnectionException, FritzResourceError) as ex: except FRITZ_EXCEPTIONS as ex:
raise ConfigEntryNotReady from ex raise ConfigEntryNotReady from ex
hass.data.setdefault(DOMAIN, {}) hass.data.setdefault(DOMAIN, {})

View File

@ -12,10 +12,7 @@ from typing import Any, TypedDict, cast
from fritzconnection import FritzConnection from fritzconnection import FritzConnection
from fritzconnection.core.exceptions import ( from fritzconnection.core.exceptions import (
FritzActionError, FritzActionError,
FritzActionFailedError,
FritzConnectionException, FritzConnectionException,
FritzInternalError,
FritzLookUpError,
FritzSecurityError, FritzSecurityError,
FritzServiceError, FritzServiceError,
) )
@ -46,6 +43,7 @@ from .const import (
DEFAULT_PORT, DEFAULT_PORT,
DEFAULT_USERNAME, DEFAULT_USERNAME,
DOMAIN, DOMAIN,
FRITZ_EXCEPTIONS,
SERVICE_CLEANUP, SERVICE_CLEANUP,
SERVICE_REBOOT, SERVICE_REBOOT,
SERVICE_RECONNECT, SERVICE_RECONNECT,
@ -188,9 +186,26 @@ class FritzBoxTools(update_coordinator.DataUpdateCoordinator):
_LOGGER.error("Unable to establish a connection with %s", self.host) _LOGGER.error("Unable to establish a connection with %s", self.host)
return return
_LOGGER.debug(
"detected services on %s %s",
self.host,
list(self.connection.services.keys()),
)
self.fritz_hosts = FritzHosts(fc=self.connection) self.fritz_hosts = FritzHosts(fc=self.connection)
self.fritz_status = FritzStatus(fc=self.connection) self.fritz_status = FritzStatus(fc=self.connection)
info = self.connection.call_action("DeviceInfo:1", "GetInfo") info = self.connection.call_action("DeviceInfo:1", "GetInfo")
_LOGGER.debug(
"gathered device info of %s %s",
self.host,
{
**info,
"NewDeviceLog": "***omitted***",
"NewSerialNumber": "***omitted***",
},
)
if not self._unique_id: if not self._unique_id:
self._unique_id = info["NewSerialNumber"] self._unique_id = info["NewSerialNumber"]
@ -529,13 +544,7 @@ class AvmWrapper(FritzBoxTools):
"Authorization Error: Please check the provided credentials and verify that you can log into the web interface", "Authorization Error: Please check the provided credentials and verify that you can log into the web interface",
exc_info=True, exc_info=True,
) )
except ( except FRITZ_EXCEPTIONS:
FritzActionError,
FritzActionFailedError,
FritzInternalError,
FritzServiceError,
FritzLookUpError,
):
_LOGGER.error( _LOGGER.error(
"Service/Action Error: cannot execute service %s with action %s", "Service/Action Error: cannot execute service %s with action %s",
service_name, service_name,

View File

@ -2,6 +2,14 @@
from typing import Literal from typing import Literal
from fritzconnection.core.exceptions import (
FritzActionError,
FritzActionFailedError,
FritzInternalError,
FritzLookUpError,
FritzServiceError,
)
from homeassistant.backports.enum import StrEnum from homeassistant.backports.enum import StrEnum
from homeassistant.const import Platform from homeassistant.const import Platform
@ -47,3 +55,11 @@ SWITCH_TYPE_PORTFORWARD = "PortForward"
SWITCH_TYPE_WIFINETWORK = "WiFiNetwork" SWITCH_TYPE_WIFINETWORK = "WiFiNetwork"
UPTIME_DEVIATION = 5 UPTIME_DEVIATION = 5
FRITZ_EXCEPTIONS = (
FritzActionError,
FritzActionFailedError,
FritzInternalError,
FritzServiceError,
FritzLookUpError,
)

View File

@ -94,16 +94,15 @@ class FritzConnectionMock: # pylint: disable=too-few-public-methods
def __init__(self): def __init__(self):
"""Inint Mocking class.""" """Inint Mocking class."""
type(self).modelname = mock.PropertyMock(return_value=self.MODELNAME) self.modelname = self.MODELNAME
self.call_action = mock.Mock(side_effect=self._side_effect_call_action) self.call_action = mock.Mock(side_effect=self._side_effect_call_action)
type(self).action_names = mock.PropertyMock( type(self).action_names = mock.PropertyMock(
side_effect=self._side_effect_action_names side_effect=self._side_effect_action_names
) )
services = { self.services = {
srv: None srv: None
for srv, _ in list(self.FRITZBOX_DATA) + list(self.FRITZBOX_DATA_INDEXED) for srv, _ in list(self.FRITZBOX_DATA) + list(self.FRITZBOX_DATA_INDEXED)
} }
type(self).services = mock.PropertyMock(side_effect=[services])
def _side_effect_call_action(self, service, action, **kwargs): def _side_effect_call_action(self, service, action, **kwargs):
if kwargs: if kwargs: