An attach-mode partial failure persists successes then records the failure 🟩

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-07 11:56:57 +00:00
parent 3cf44d6409
commit bf0d630a8f

View file

@ -65,7 +65,7 @@ from domain.modelling.plan import Plan
from domain.property.property import Property, PropertyIdentity
from domain.property_baseline.calculator_rebaseliner import CalculatorRebaseliner
from domain.sap10_calculator.calculator import Sap10Calculator
from domain.tasks.subtasks import SubTask
from domain.tasks.subtasks import SubTask, SubTaskFailure
from domain.tasks.tasks import Source
from harness.console import run_modelling
from orchestration.task_orchestrator import TaskOrchestrator
@ -687,12 +687,21 @@ def handler(
)
logger.info(f"property={pid} queued for write")
failed_properties: list[dict[str, Any]] = []
if trigger.subtask_id is not None:
# Attach mode (ADR-0055): the whole batch runs under the
# distributor's pre-created sub_task — the @task_handler wrapper is
# already inside it — so no per-property children are created.
# Failures stay isolated per property (siblings continue) and are
# recorded on the sub_task after the surviving writes flush.
for pid in property_ids:
_model_property(pid)
try:
_model_property(pid)
except Exception as exc: # noqa: BLE001 — recorded below
logger.exception(f"property={pid} failed")
failed_properties.append(
{"property_id": pid, "error": str(exc)}
)
else:
# Fan the batch out into one child SubTask per property and run
# them in a single batched pass: create all children, model each
@ -732,5 +741,18 @@ def handler(
f"{[s['certificate_number'] for s in skipped_certs]}"
)
# Raised only after the surviving writes flushed: the failure is a
# record on the sub_task, never an SQS retry (ADR-0055). Recovery is a
# deliberate re-send of the sub_task's own inputs.
if failed_properties:
raise SubTaskFailure(
f"{len(failed_properties)} of {len(property_ids)} "
"properties failed",
details={
"succeeded": len(property_ids) - len(failed_properties),
"failed": failed_properties,
},
)
finally:
read_session.close()