Skip to content

Log unexpected errors in api_process wrappers#6739

Open
agners wants to merge 3 commits intomainfrom
make-sure-to-log-errors-on-api-level
Open

Log unexpected errors in api_process wrappers#6739
agners wants to merge 3 commits intomainfrom
make-sure-to-log-errors-on-api-level

Conversation

@agners
Copy link
Copy Markdown
Member

@agners agners commented Apr 15, 2026

Proposed change

The api_process and api_process_raw decorators silently swallowed any HassioError that bubbled up from endpoint handlers. The wrapped handler caught the exception, returned an error response, but never logged anything. When the exception also had no message (e.g. DBusNotConnectedError raised without arguments by @dbus_connected), api_return_error falls back to "Unknown error, see Supervisor logs" — telling the caller to check logs that contain literally nothing about the failure.

Concretely, Core's analytics.save_preferences hitting POST /supervisor/options with diagnostics=true on a host without OS-Agent on the bus (e.g. the Supervisor devcontainer) produces:

aiohasupervisor.exceptions.SupervisorBadRequestError: Unknown error, see Supervisor logs

…with no corresponding Supervisor log line to go look at.

This PR logs the caught HassioError with traceback in both api_process and api_process_raw before delegating to api_return_error, so the "see Supervisor logs" hint is actually actionable. The APIError branch is intentionally left alone — those carry explicit status codes and messages set by Supervisor code and are already visible in the response, so logging them would just be noise (e.g. validation errors).

This does not fix the underlying missing message on DBusNotConnectedError itself (that's a follow-up), but it makes any future occurrence of this pattern diagnosable from the logs alone.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (which adds functionality to the supervisor)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request:
  • Link to cli pull request:
  • Link to client library pull request:

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • The code has been formatted using Ruff (ruff format supervisor tests)
  • Tests have been added to verify that the new code works.

If API endpoints or add-on configuration are added/changed:

The `api_process` and `api_process_raw` decorators silently swallowed
any `HassioError` that bubbled up from endpoint handlers, returning
`"Unknown error, see Supervisor logs"` to the caller while logging
nothing. This made the response message actively misleading: e.g. when
an endpoint touching D-Bus hit `DBusNotConnectedError` (raised without
a message by `@dbus_connected`), Core would surface
`SupervisorBadRequestError: Unknown error, see Supervisor logs` and
the Supervisor logs would contain no trace of it.

Log the caught `HassioError` with traceback before delegating to
`api_return_error` so the "see Supervisor logs" hint is actually
actionable. The `APIError` branch is left alone — those carry explicit
status codes and messages set by Supervisor code and are already
visible in the response.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@agners agners added the bugfix A bug fix label Apr 15, 2026
Copy link
Copy Markdown
Contributor

@mdegat01 mdegat01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this. It feels like the flaw might be with the point at which the exception is raised though. HassioError means handled and if logging to inform the user is needed we should do that at the point we raise it right?

@agners
Copy link
Copy Markdown
Member Author

agners commented Apr 16, 2026

I'm fine with this. It feels like the flaw might be with the point at which the exception is raised though. HassioError means handled and if logging to inform the user is needed we should do that at the point we raise it right?

"HassioError means handled" is maybe a bit overstatement. I means it is an exception created by us, but some of them are quite low level and come without any text (like the DBusNotConnectedError case showed).

IMHO, for the well handled exception cases we should have exception classes deriving from APIError and those should have user friendly strings. I guess we have quite some of them covered. What is left are HassioError derrived exception. Those are either cases where we just missed adding a good exception class (we should find those) or very rare exception we don't want to handle (e.g. happen due to very specific set of rare circumstances like corruption or weird system setup).

This PR is about HassioError. And I am tempted to report them to Sentry, but I fear the volume of such exception is maybe to high 🤔 .

Non-APIError HassioError exceptions reaching api_process indicate
missing error handling in the endpoint handler. In addition to the
logging added in the previous commit, also send these to Sentry so
they surface as actionable issues rather than silently returning
"Unknown error, see Supervisor logs" to the caller.
Copy link
Copy Markdown
Contributor

@mdegat01 mdegat01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I get it now. HassioError captured after APIError so its specifically to catch the non-APIError exceptions raised. This makes sense then.

As for sentry noise, I don't really know how much this will be. I think passing them to sentry and letting it aggregate them for us provides us the best way to track them down and improve handling so I'd say lets try it. If its clearly too noisy we'll drop it if necessary but I'd rather just quickly address the main problem points if possible with better logging and an APIError instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants