From ebe6ab9741ab091533f4b543f413c62aaf461713 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 17 Jun 2026 11:40:36 -0400 Subject: [PATCH] refactor(native-ingest): shared exception trio + base _failure_result (#899 DRY 2/3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DRY pass commit 2. The two adapters re-implemented the same auth→drift→429→404 →http→network mapping in _failure_result; only the exception classes + drift phrasing differed (divergence-bug risk: a new error_type handled in one and not the other). - native_ingest_common gains NativeIngestError / NativeAuthError / NativeDriftError (status_code + retry_after on the base). Patreon{API,Auth,Drift}Error and SubscribeStar{API,Auth,Drift}Error now subclass them via multiple inheritance, keeping their isinstance-distinct platform names. - Ingester._failure_result (base) does the whole mapping via the shared NativeAuthError/NativeDriftError taxonomy + status_code; a new platform gets it free. New drift_label kwarg supplies the per-platform API_DRIFT phrasing ("Patreon API" / "SubscribeStar markup"), preserving the existing message (test asserts "Patreon API changed"). - Both adapters drop their near-identical _failure_result overrides and their now -unused DownloadResult/ErrorType/*Auth/*Drift imports. Verified at every consumer (rule 93/§8b): test_patreon_ingester (auth/drift/429/ 404/network) and test_subscribestar_native (_failure_result mapping) both exercise the base method now. Remaining: ingest_core L1/L3 logging (3/3). Co-Authored-By: Claude Opus 4.8 --- backend/app/services/ingest_core.py | 44 +++++++++++++-- backend/app/services/native_ingest_common.py | 35 ++++++++++++ backend/app/services/patreon_client.py | 31 +++-------- backend/app/services/patreon_ingester.py | 55 ++----------------- backend/app/services/subscribestar_client.py | 25 +++------ .../app/services/subscribestar_ingester.py | 44 ++------------- 6 files changed, 98 insertions(+), 136 deletions(-) diff --git a/backend/app/services/ingest_core.py b/backend/app/services/ingest_core.py index ba628f7..5cfaf5c 100644 --- a/backend/app/services/ingest_core.py +++ b/backend/app/services/ingest_core.py @@ -36,6 +36,7 @@ from sqlalchemy import delete, func, select, text from sqlalchemy.dialects.postgresql import insert as pg_insert from .gallery_dl import DownloadResult, ErrorType, make_run_stats +from .native_ingest_common import NativeAuthError, NativeDriftError log = logging.getLogger(__name__) @@ -88,6 +89,7 @@ class Ingester: ledger_key: Callable[[object], str], platform: str, error_base: type[Exception], + drift_label: str | None = None, ): self.client = client self.downloader = downloader @@ -99,6 +101,10 @@ class Ingester: self._ledger_key = ledger_key self._platform = platform self._error_base = error_base + # Human label for the API_DRIFT message ("