From 58b7be7c2ffa1125c6d7bcc98d7617efbf1a86a0 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Mon, 3 Feb 2025 17:33:03 +0100 Subject: [PATCH] Check for errors when creating backups using supervisor (#137220) * Check for errors when creating backups using supervisor * Improve error reporting when there's no backup reference --- homeassistant/components/hassio/backup.py | 9 ++++-- tests/components/hassio/test_backup.py | 37 ++++++++++++++++++----- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/hassio/backup.py b/homeassistant/components/hassio/backup.py index 34d1c62aed7..4aad984cc54 100644 --- a/homeassistant/components/hassio/backup.py +++ b/homeassistant/components/hassio/backup.py @@ -354,6 +354,7 @@ class SupervisorBackupReaderWriter(BackupReaderWriter): """Wait for a backup to complete.""" backup_complete = asyncio.Event() backup_id: str | None = None + create_errors: list[dict[str, str]] = [] @callback def on_job_progress(data: Mapping[str, Any]) -> None: @@ -361,6 +362,7 @@ class SupervisorBackupReaderWriter(BackupReaderWriter): nonlocal backup_id if data.get("done") is True: backup_id = data.get("reference") + create_errors.extend(data.get("errors", [])) backup_complete.set() unsub = self._async_listen_job_events(backup.job_id, on_job_progress) @@ -369,8 +371,11 @@ class SupervisorBackupReaderWriter(BackupReaderWriter): await backup_complete.wait() finally: unsub() - if not backup_id: - raise BackupReaderWriterError("Backup failed") + if not backup_id or create_errors: + # We should add more specific error handling here in the future + raise BackupReaderWriterError( + f"Backup failed: {create_errors or 'no backup_id'}" + ) async def open_backup() -> AsyncIterator[bytes]: try: diff --git a/tests/components/hassio/test_backup.py b/tests/components/hassio/test_backup.py index f35ddeaabbd..ab3335e00dc 100644 --- a/tests/components/hassio/test_backup.py +++ b/tests/components/hassio/test_backup.py @@ -1360,11 +1360,40 @@ async def test_reader_writer_create_partial_backup_error( assert supervisor_client.backups.partial_backup.call_count == 1 +@pytest.mark.parametrize( + "supervisor_event", + [ + # Missing backup reference + { + "event": "job", + "data": { + "done": True, + "uuid": TEST_JOB_ID, + }, + }, + # Errors + { + "event": "job", + "data": { + "done": True, + "errors": [ + { + "type": "BackupMountDownError", + "message": "test_mount is down, cannot back-up to it", + } + ], + "uuid": TEST_JOB_ID, + "reference": "test_slug", + }, + }, + ], +) @pytest.mark.usefixtures("hassio_client", "setup_integration") async def test_reader_writer_create_missing_reference_error( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, supervisor_client: AsyncMock, + supervisor_event: dict[str, Any], ) -> None: """Test missing reference error when generating a backup.""" client = await hass_ws_client(hass) @@ -1395,13 +1424,7 @@ async def test_reader_writer_create_missing_reference_error( assert supervisor_client.backups.partial_backup.call_count == 1 await client.send_json_auto_id( - { - "type": "supervisor/event", - "data": { - "event": "job", - "data": {"done": True, "uuid": TEST_JOB_ID}, - }, - } + {"type": "supervisor/event", "data": supervisor_event} ) response = await client.receive_json() assert response["success"]