SPB Git forge

spb/lou-ka

Public

Lou·Ka — tous les logements à louer du Québec, un seul endroit.

232commits 1branches 0releases
172.9 MBsize
maindefault branch
2 days agolast push
HTML 98.9% Python 0.6%

[ka2] fix connecteur thrace: échec honnête au lieu d'un « 0 trouvé ok » qui menaçait les 158 annonces. Le sync du 2026-09-08 11:00 a rapporté found=0 ok=1 (dérive vs médiane 153, retraits suspendus par le garde-fou) : le fetch() avalait toute exception par projet Livya (`except Exception: continue` sur thrace, radisson et carree-radisson) — une erreur réseau transitoire sur app.livya.com devenait un succès à 0 résultat, invisible du disjoncteur d'ingest.py. Reproduit en live : les 3 pages plans répondent 200 (0,9–6 Mo) et 538 unités brutes se parsent — la source est saine, seul le silence sur erreur était fautif. On laisse désormais l'exception réseau remonter (ingest journalise ok=0) et on lève RuntimeError si une page plans ne parse aucun objet unitId du flux RSC (garde contre un rendu partiel 200 — chaque page en publie des dizaines, tous statuts confondus ; même pattern que les fix le_fjord 472920e et logiluxx 1814e48). Testé : run.py sync thrace → found=151 ok (médiane 153, updated=1), pm2 restart lou-ka-sync, site :8095 → 200.

Simon-Pierre Boucher committed 16 days ago (Sep 8, 2026) parent 1064e80

1 changed file +16 −7

modified louka/connectors/thrace.py +16 −7
@@ -116,17 +116,26 @@ class ThraceConnector(BaseConnector):
116 116 client, entity = self._module_params()
117 117 projects = self._project_slugs(client)
118 118
119 + # échec HONNÊTE : une erreur réseau ou un rendu Next.js partiel (200
120 + # sans objets unitId dans le flux RSC) doit lever (ok=0 dans sync_log)
121 + # et non retourner [] — l'ancien `except Exception: continue` sur les
122 + # 3 projets a produit le « 0 trouvé ok » du 2026-09-08 11:00 alors que
123 + # la source était saine (même pattern que les fix le_fjord/logiluxx)
119 124 units: dict[str, dict] = {}
120 125 buildings: dict[str, tuple[str, str]] = {} # id -> (nom, slug)
121 126 for slug in projects:
122 − try:
123 − html = self.get(
124 − f"{LIVYA}/fr/{client}/projects/{slug}/plans/{entity}",
125 − params={"noLayout": "1"}).text
126 − except Exception:
127 − continue # un projet cassé ne bloque pas
127 + html = self.get(
128 + f"{LIVYA}/fr/{client}/projects/{slug}/plans/{entity}",
129 + params={"noLayout": "1"}).text
128 130 blob = _flight_blob(html)
129 − for u in self._units(blob):
131 + page_units = self._units(blob)
132 + if not page_units:
133 + # chaque page plans publie des dizaines d'unités (tous statuts
134 + # confondus) : zéro = rendu partiel/illisible, pas un vide réel
135 + raise RuntimeError(
136 + f"aucun objet unitId dans le flux RSC du projet {slug} "
137 + f"({len(html)} o) — rendu partiel ?")
138 + for u in page_units:
130 139 units.setdefault(u["unitId"], u)
131 140 for bid, name, bslug in _BUILDING_RE.findall(blob):
132 141 buildings.setdefault(bid, (name, bslug))
133 142