From 81d25caeadf05d28ae406bd6c325241b3e466cf4 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Mon, 6 Jul 2026 13:35:47 +0000 Subject: [PATCH] =?UTF-8?q?A=20failed=20HubSpot=20write=20stops=20the=20sy?= =?UTF-8?q?nc=20and=20reports=20the=20orphaned=20contacts=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 --- .../tenant_data_sync_orchestrator.py | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/orchestration/tenant_data_sync_orchestrator.py b/orchestration/tenant_data_sync_orchestrator.py index aa8005bd8..383ca2a98 100644 --- a/orchestration/tenant_data_sync_orchestrator.py +++ b/orchestration/tenant_data_sync_orchestrator.py @@ -3,6 +3,7 @@ from typing import Dict, List, Optional, Tuple, Union from domain.abri.models import AbriRequestRejected, PlaceRef, Tenant from etl.hubspot.deal_contacts_client import HubspotDealContactsClient +from etl.hubspot.errors import HubspotRequestError from infrastructure.abri.abri_client import AbriClient @@ -106,12 +107,27 @@ class TenantDataSyncOrchestrator: return tenancy contact_ids: List[str] = [] - for tenant in tenancy.tenants: - contact_id = self._hubspot.create_contact(_contact_properties(tenant)) - self._hubspot.associate_contact_to_deal( - deal_id=deal_id, contact_id=contact_id - ) - contact_ids.append(contact_id) + associated_ids: List[str] = [] + for tenant_index, tenant in enumerate(tenancy.tenants): + try: + contact_id = self._hubspot.create_contact( + _contact_properties(tenant) + ) + contact_ids.append(contact_id) + self._hubspot.associate_contact_to_deal( + deal_id=deal_id, contact_id=contact_id + ) + associated_ids.append(contact_id) + except HubspotRequestError as error: + # Fail fast at the first failed write; `error` is already + # scrubbed, so chaining it keeps tracebacks PII-free. + raise TenantDataSyncError( + message=str(error), + deal_id=deal_id, + tenant_index=tenant_index, + contact_ids_created=tuple(contact_ids), + contact_ids_associated=tuple(associated_ids), + ) from error return TenantDataSyncSummary( tenancy_reference=tenancy.tenancy_reference,