[ka6] fix connecteur qublivre.ca: catalogue >25 000 produits — l'endpoint public Shopify /products.json renvoie HTTP 400 « Page * Limit exceeds the 25000 limit » à la page 101, et le connecteur propageait ce 400 comme une panne (3 syncs à 0, jamais un succès). Le site est de surcroît derrière un challenge Cloudflare (429 cf-mitigated même en direct), donc tout passe par l'escalade Scrapfly existante — c'est elle qui remontait le « scrapfly upstream 400 ». shopify.py: nouvelle _PageCapError levée sur HTTP 400 (curl direct, sans retry inutile) et sur « upstream 400 » Scrapfly (court-circuite les 3 retries), attrapée dans fetch(): fin de pagination propre si page>1 avec des produits déjà récoltés, re-levée sinon. Sync réel: 0→25 000 produits en 538 s (0 erreur, cap Shopify atteint proprement), 25 000/25 000 avec prix, 24 866 avec image, 1 fiche vérifiée contre la page live (N'écoute pas la nuit, 27,95 $).
1 changed file +16 −1
modified
fabrika/connectors/shopify.py
+16 −1
@@ -20,6 +20,12 @@ _MIN_INTERVAL = 0.7 | ||
| 20 | 20 | _last_shopify_req = [0.0] |
| 21 | 21 | |
| 22 | 22 | |
| 23 | +class _PageCapError(RuntimeError): | |
| 24 | + """HTTP 400 « Page * Limit exceeds the 25000 limit » : /products.json | |
| 25 | + refuse toute page au-delà de 25 000 produits — fin de pagination, pas | |
| 26 | + une panne (ex. qublivre.ca, >25 k livres).""" | |
| 27 | + | |
| 28 | + | |
| 23 | 29 | class ShopifyConnector(BaseConnector): |
| 24 | 30 | platform = "shopify" |
| 25 | 31 | |
@@ -62,6 +68,8 @@ class ShopifyConnector(BaseConnector): | ||
| 62 | 68 | elif code == "429": |
| 63 | 69 | time.sleep(8 * (attempt + 1)) |
| 64 | 70 | last_err = RuntimeError("429 Too Many Requests") |
| 71 | + elif code == "400": | |
| 72 | + raise _PageCapError(f"HTTP 400 {url}") | |
| 65 | 73 | else: |
| 66 | 74 | last_err = RuntimeError(f"HTTP {code or 'error'} {p.stderr[:120]}") |
| 67 | 75 | time.sleep(2) |
@@ -84,6 +92,8 @@ class ShopifyConnector(BaseConnector): | ||
| 84 | 92 | try: |
| 85 | 93 | return scrapfly.scrapfly_json(url) |
| 86 | 94 | except Exception as exc: |
| 95 | + if "upstream 400" in str(exc): | |
| 96 | + raise _PageCapError(str(exc)) from exc | |
| 87 | 97 | last_err = exc |
| 88 | 98 | time.sleep(3 * (attempt + 1)) |
| 89 | 99 | raise RuntimeError(f"{url}: scrapfly: {last_err}") |
@@ -92,7 +102,12 @@ class ShopifyConnector(BaseConnector): | ||
| 92 | 102 | out: list[Product] = [] |
| 93 | 103 | page = 1 |
| 94 | 104 | while page <= self.max_pages: |
| 95 | − data = self._get_json(f"{self.base}/products.json?limit=250&page={page}") | |
| 105 | + try: | |
| 106 | + data = self._get_json(f"{self.base}/products.json?limit=250&page={page}") | |
| 107 | + except _PageCapError: | |
| 108 | + if page > 1 and out: | |
| 109 | + break | |
| 110 | + raise | |
| 96 | 111 | items = data.get("products", []) |
| 97 | 112 | if not items: |
| 98 | 113 | break |
| 99 | 114 | |