mirror of
https://github.com/home-assistant/supervisor.git
synced 2026-05-24 08:38:48 +01:00
Log unexpected errors in api_process wrappers (#6739)
* Log unexpected errors in api_process wrappers 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> * Capture unexpected API errors to Sentry 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. * Drop capture exception from set_boot_slot --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import asyncio
|
||||
from collections.abc import Callable, Mapping
|
||||
import json
|
||||
import logging
|
||||
from typing import Any, cast
|
||||
|
||||
from aiohttp import web
|
||||
@@ -31,8 +32,11 @@ from ..jobs import JobSchedulerOptions, SupervisorJob
|
||||
from ..utils import check_exception_chain, get_message_from_exception_chain
|
||||
from ..utils.json import json_dumps, json_loads as json_loads_util
|
||||
from ..utils.log_format import format_message
|
||||
from ..utils.sentry import async_capture_exception
|
||||
from . import const
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def extract_supervisor_token(request: web.Request) -> str | None:
|
||||
"""Extract Supervisor token from request."""
|
||||
@@ -72,6 +76,8 @@ def api_process(method):
|
||||
err, status=err.status, job_id=err.job_id, headers=err.headers
|
||||
)
|
||||
except HassioError as err:
|
||||
_LOGGER.exception("Unexpected error during API call: %s", err)
|
||||
await async_capture_exception(err)
|
||||
return api_return_error(err)
|
||||
|
||||
if isinstance(answer, (dict, list)):
|
||||
@@ -119,6 +125,8 @@ def api_process_raw(content, *, error_type=None):
|
||||
job_id=err.job_id,
|
||||
)
|
||||
except HassioError as err:
|
||||
_LOGGER.exception("Unexpected error during API call: %s", err)
|
||||
await async_capture_exception(err)
|
||||
return api_return_error(
|
||||
err, error_type=error_type or const.CONTENT_TYPE_BINARY
|
||||
)
|
||||
|
||||
@@ -22,7 +22,6 @@ from ..exceptions import (
|
||||
)
|
||||
from ..jobs.const import JobConcurrency, JobCondition
|
||||
from ..jobs.decorator import Job
|
||||
from ..utils.sentry import async_capture_exception
|
||||
from .data_disk import DataDisk
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
@@ -363,7 +362,6 @@ class OSManager(CoreSysAttributes):
|
||||
RaucState.ACTIVE, self.get_slot_name(boot_name)
|
||||
)
|
||||
except DBusError as err:
|
||||
await async_capture_exception(err)
|
||||
raise HassOSSlotUpdateError(
|
||||
f"Can't mark {boot_name} as active!", _LOGGER.error
|
||||
) from err
|
||||
|
||||
Reference in New Issue
Block a user