Skip to content

Commit

Permalink
Improve and extend error handling on D-Bus connect
Browse files Browse the repository at this point in the history
Avoid initializing the Supervisor board since it does not support the
Properties interface (see home-assistant/os-agent#206).

This prevents the following somewhat confusing warning:
  No OS-Agent support on the host. Some Host functions have been disabled.

The OS Agent is actually installed on the host, it is just a single
object which caused issues. No functionalty was actually lost, as the
Supervisor board object has no features currently, and all other
interfaces got properly initialized still (thanks to gather()).

Print warnings more fine graned so it is clear which object exactly
causes an issue. Also print a log message on the lowest layer when an
error occures on calling D-Bus. This allows to easier track the actual
D-Bus error source.

Fixes: #5241
  • Loading branch information
agners committed Aug 13, 2024
1 parent f6faa18 commit 4eaff4d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 11 deletions.
21 changes: 16 additions & 5 deletions supervisor/dbus/agent/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from awesomeversion import AwesomeVersion
from dbus_fast.aio.message_bus import MessageBus

from ...exceptions import DBusError, DBusInterfaceError, DBusServiceUnkownError
from ...exceptions import DBusInterfaceError, DBusServiceUnkownError
from ..const import (
DBUS_ATTR_DIAGNOSTICS,
DBUS_ATTR_VERSION,
Expand Down Expand Up @@ -96,13 +96,24 @@ async def connect(self, bus: MessageBus) -> None:
_LOGGER.info("Load dbus interface %s", self.name)
try:
await super().connect(bus)
await asyncio.gather(*[dbus.connect(bus) for dbus in self.all])
except DBusError:
_LOGGER.warning("Can't connect to OS-Agent")
except (DBusServiceUnkownError, DBusInterfaceError):
_LOGGER.warning(
_LOGGER.error(
"No OS-Agent support on the host. Some Host functions have been disabled."
)
return

errors = await asyncio.gather(
*[dbus.connect(bus) for dbus in self.all], return_exceptions=True
)

for err in errors:
if err:
_LOGGER.error(
"Can't load OS Agent dbus interface %s %s: %s",
self.all[errors.index(err)].bus_name,
self.all[errors.index(err)].object_path,
err,
)

@dbus_connected
async def update(self, changed: dict[str, Any] | None = None) -> None:
Expand Down
18 changes: 13 additions & 5 deletions supervisor/dbus/agent/boards/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from dbus_fast.aio.message_bus import MessageBus

from ....exceptions import BoardInvalidError
from ....exceptions import BoardInvalidError, DBusInterfaceError, DBusServiceUnkownError
from ...const import (
DBUS_ATTR_BOARD,
DBUS_IFACE_HAOS_BOARDS,
Expand Down Expand Up @@ -73,8 +73,16 @@ async def connect(self, bus: MessageBus) -> None:
self._board_proxy = Yellow()
elif self.board == BOARD_NAME_GREEN:
self._board_proxy = Green()
elif self.board == BOARD_NAME_SUPERVISED:
self._board_proxy = Supervised()

if self._board_proxy:
# Currently unused, avoid initialization due to a bug in introspection:
# See: https://github.com/home-assistant/os-agent/issues/206
# elif self.board == BOARD_NAME_SUPERVISED:
# self._board_proxy = Supervised()
else:
return

try:
await self._board_proxy.connect(bus)
except (DBusServiceUnkownError, DBusInterfaceError) as ex:
_LOGGER.warning(
"OS-Agent Board support initialization failed.", exc_info=ex
)
3 changes: 2 additions & 1 deletion supervisor/dbus/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,9 @@ async def load(self) -> None:
for err in errors:
if err:
_LOGGER.warning(
"Can't load dbus interface %s: %s",
"Can't load dbus interface %s %s: %s",
self.all[errors.index(err)].name,
self.all[errors.index(err)].object_path,
err,
)

Expand Down
7 changes: 7 additions & 0 deletions supervisor/utils/dbus.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ async def call_dbus(
)
return await getattr(proxy_interface, method)(*args)
except DBusFastDBusError as err:
_LOGGER.debug(
"D-Bus fast error on call - %s.%s on %s: %s",
proxy_interface.introspection.name,
method,
proxy_interface.path,
err,
)
raise DBus.from_dbus_error(err) from None
except Exception as err: # pylint: disable=broad-except
capture_exception(err)
Expand Down

0 comments on commit 4eaff4d

Please sign in to comment.