From 59ef8a12aba7ac7f810a61ffca8dd327df29ffc2 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Wed, 8 Jul 2026 09:33:25 +0000 Subject: [PATCH] =?UTF-8?q?Treat=20a=20selection=20with=20no=20documents?= =?UTF-8?q?=20as=20a=20recorded=20failure=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../bulk_document_download_orchestrator.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/orchestration/bulk_document_download_orchestrator.py b/orchestration/bulk_document_download_orchestrator.py index 54de823bb..39ee7271e 100644 --- a/orchestration/bulk_document_download_orchestrator.py +++ b/orchestration/bulk_document_download_orchestrator.py @@ -21,6 +21,7 @@ from domain.bulk_document_download.package_plan import ( SkippedDocument, plan_download_package, ) +from domain.tasks.subtasks import SubTaskFailure from infrastructure.postgres.uploaded_file_table import UploadedFile from infrastructure.s3.s3_client import S3Client from repositories.email.email_sender import EmailSender @@ -81,6 +82,23 @@ class BulkDocumentDownloadOrchestrator: resolved = [self._resolve(file) for file in files] plan = plan_download_package([r for r in resolved if r is not None]) + if not plan.entries: + # Nothing to package (ADR-0060): a recorded failure, not an empty + # ZIP emailed to the user. The skip detail rides on the failure. + raise SubTaskFailure( + "no documents resolved for the selection", + details={ + "skipped": [ + { + "landlord_property_id": s.landlord_property_id, + "s3_key": s.s3_key, + "reason": s.reason, + } + for s in plan.skipped + ] + }, + ) + buffer = io.BytesIO() with zipfile.ZipFile(buffer, "w", zipfile.ZIP_DEFLATED) as archive: for entry in plan.entries: