Improve mikrotik error handling (#106244)

* improve mikrotik error handling

* switch to debug

* fix mock command arguments

* add recommendations

---------

Co-authored-by: Marco98 <Marco98@users.noreply.github.com>
This commit is contained in:
Marco 2023-12-23 16:26:27 +01:00 committed by GitHub
parent 0af850cbb6
commit d450a7f57e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 14 deletions

View File

@ -91,7 +91,7 @@ class MikrotikData:
def get_info(self, param: str) -> str: def get_info(self, param: str) -> str:
"""Return device model name.""" """Return device model name."""
cmd = IDENTITY if param == NAME else INFO cmd = IDENTITY if param == NAME else INFO
if data := self.command(MIKROTIK_SERVICES[cmd]): if data := self.command(MIKROTIK_SERVICES[cmd], suppress_errors=(cmd == INFO)):
return str(data[0].get(param)) return str(data[0].get(param))
return "" return ""
@ -101,10 +101,18 @@ class MikrotikData:
self.model = self.get_info(ATTR_MODEL) self.model = self.get_info(ATTR_MODEL)
self.firmware = self.get_info(ATTR_FIRMWARE) self.firmware = self.get_info(ATTR_FIRMWARE)
self.serial_number = self.get_info(ATTR_SERIAL_NUMBER) self.serial_number = self.get_info(ATTR_SERIAL_NUMBER)
self.support_capsman = bool(self.command(MIKROTIK_SERVICES[IS_CAPSMAN])) self.support_capsman = bool(
self.support_wireless = bool(self.command(MIKROTIK_SERVICES[IS_WIRELESS])) self.command(MIKROTIK_SERVICES[IS_CAPSMAN], suppress_errors=True)
self.support_wifiwave2 = bool(self.command(MIKROTIK_SERVICES[IS_WIFIWAVE2])) )
self.support_wifi = bool(self.command(MIKROTIK_SERVICES[IS_WIFI])) self.support_wireless = bool(
self.command(MIKROTIK_SERVICES[IS_WIRELESS], suppress_errors=True)
)
self.support_wifiwave2 = bool(
self.command(MIKROTIK_SERVICES[IS_WIFIWAVE2], suppress_errors=True)
)
self.support_wifi = bool(
self.command(MIKROTIK_SERVICES[IS_WIFI], suppress_errors=True)
)
def get_list_from_interface(self, interface: str) -> dict[str, dict[str, Any]]: def get_list_from_interface(self, interface: str) -> dict[str, dict[str, Any]]:
"""Get devices from interface.""" """Get devices from interface."""
@ -205,7 +213,10 @@ class MikrotikData:
return True return True
def command( def command(
self, cmd: str, params: dict[str, Any] | None = None self,
cmd: str,
params: dict[str, Any] | None = None,
suppress_errors: bool = False,
) -> list[dict[str, Any]]: ) -> list[dict[str, Any]]:
"""Retrieve data from Mikrotik API.""" """Retrieve data from Mikrotik API."""
_LOGGER.debug("Running command %s", cmd) _LOGGER.debug("Running command %s", cmd)
@ -224,12 +235,11 @@ class MikrotikData:
# we still have to raise CannotConnect to fail the update. # we still have to raise CannotConnect to fail the update.
raise CannotConnect from api_error raise CannotConnect from api_error
except librouteros.exceptions.ProtocolError as api_error: except librouteros.exceptions.ProtocolError as api_error:
_LOGGER.warning( emsg = "Mikrotik %s failed to retrieve data. cmd=[%s] Error: %s"
"Mikrotik %s failed to retrieve data. cmd=[%s] Error: %s", if suppress_errors and "no such command prefix" in str(api_error):
self._host, _LOGGER.debug(emsg, self._host, cmd, api_error)
cmd, return []
api_error, _LOGGER.warning(emsg, self._host, cmd, api_error)
)
return [] return []

View File

@ -175,7 +175,12 @@ async def setup_mikrotik_entry(hass: HomeAssistant, **kwargs: Any) -> None:
wireless_data: list[dict[str, Any]] = kwargs.get("wireless_data", WIRELESS_DATA) wireless_data: list[dict[str, Any]] = kwargs.get("wireless_data", WIRELESS_DATA)
wifiwave2_data: list[dict[str, Any]] = kwargs.get("wifiwave2_data", WIFIWAVE2_DATA) wifiwave2_data: list[dict[str, Any]] = kwargs.get("wifiwave2_data", WIFIWAVE2_DATA)
def mock_command(self, cmd: str, params: dict[str, Any] | None = None) -> Any: def mock_command(
self,
cmd: str,
params: dict[str, Any] | None = None,
suppress_errors: bool = False,
) -> Any:
if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIRELESS]: if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIRELESS]:
return support_wireless return support_wireless
if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIFIWAVE2]: if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIFIWAVE2]:

View File

@ -52,7 +52,9 @@ def mock_device_registry_devices(hass: HomeAssistant) -> None:
) )
def mock_command(self, cmd: str, params: dict[str, Any] | None = None) -> Any: def mock_command(
self, cmd: str, params: dict[str, Any] | None = None, suppress_errors: bool = False
) -> Any:
"""Mock the Mikrotik command method.""" """Mock the Mikrotik command method."""
if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIRELESS]: if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIRELESS]:
return True return True