[ka6] fix connecteur immunotec.com: retry (4 essais, backoff 5s/10s/15s) sur le POST product-wall Scrapfly — Cloudflare renvoie par intermittence un 200 au corps vide/non-JSON selon l'IP Scrapfly du moment (historique sync_log: ~2 succès sur 12, erreur « Expecting value: line 1 column 1 »), l'API et le parsing sont inchangés (6/6 sondes JSON valides); erreur désormais explicite (statut + extrait du corps) au lieu du json.loads brut. Sync réel: 49 produits / statut ok (= médiane 49.0)
1 changed file +19 −6
modified
fabrika/connectors/immunotec.py
+19 −6
@@ -12,6 +12,7 @@ from __future__ import annotations | ||
| 12 | 12 | |
| 13 | 13 | import json |
| 14 | 14 | import re |
| 15 | +import time | |
| 15 | 16 | import unicodedata |
| 16 | 17 | |
| 17 | 18 | from ..schema import Product, parse_price |
@@ -44,12 +45,24 @@ class ImmunotecConnector(BaseConnector): | ||
| 44 | 45 | "categoryId": category_id, "isConsultant": False, |
| 45 | 46 | "downlineCustomerId": 0, "isShareCart": False, |
| 46 | 47 | "isEnrollment": False} |
| 47 | − status, content = scrapfly_post(API_BASE + WALL_PATH, body, | |
| 48 | − headers=API_HEADERS) | |
| 49 | − if status != 200: | |
| 50 | − raise RuntimeError(f"immunotec product-wall {status}") | |
| 51 | − data = json.loads(content) | |
| 52 | − return ((data.get("records") or {}).get("items") or []) if data.get("status") else [] | |
| 48 | + # Cloudflare laisse parfois passer un 200 au corps vide/HTML selon | |
| 49 | + # l'IP Scrapfly du moment : on réessaie avant de déclarer l'échec. | |
| 50 | + last = "?" | |
| 51 | + for attempt in range(4): | |
| 52 | + if attempt: | |
| 53 | + time.sleep(5 * attempt) | |
| 54 | + status, content = scrapfly_post(API_BASE + WALL_PATH, body, | |
| 55 | + headers=API_HEADERS) | |
| 56 | + if status == 200: | |
| 57 | + try: | |
| 58 | + data = json.loads(content) | |
| 59 | + except ValueError: | |
| 60 | + last = f"200 non-JSON ({content[:60]!r})" | |
| 61 | + continue | |
| 62 | + return ((data.get("records") or {}).get("items") or []) \ | |
| 63 | + if data.get("status") else [] | |
| 64 | + last = f"HTTP {status}" | |
| 65 | + raise RuntimeError(f"immunotec product-wall: {last} après 4 essais") | |
| 53 | 66 | |
| 54 | 67 | def _all_category_id(self) -> int: |
| 55 | 68 | """Relit le webCategoryId « Tous les produits » depuis la page du mur.""" |
| 56 | 69 | |