SPB Git

spb/lou-ka

Public

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

[ka2] fix connecteur sotramont: hoquets « 200 sans cartes » récurrents retryables sur le portfolio. Au sync de 21:18 le connecteur a échoué (stale) sur une page 200 servie SANS cartes article.c--article-project — 2e épisode du même hoquet (10-17, conclu « rien à faire » : il revient), alors que le connecteur est sain (found=8 stable, re-testé live : 200, 152 occurrences de c--article-project, fetch venv → 8 unités). Le retry du fix 09-21 ne couvrait que l'échec du GET : un 200 vide partait directement en erreur franche et tuait le sync sur un hoquet isolé. Fix minimal (patron morin ae6ac03 / groupe_robin 3f5c9dc) : la boucle de retry ×3 (backoff 0/3/6 s) couvre désormais AUSSI le cas « GET ok mais 0 carte » ; erreurs franches inchangées après 3 échecs (pas de zéro silencieux), distinction conservée entre portfolio inaccessible et gabarit remanié. Fixtures inchangées, pytest sotramont 2 passed. Testé : fetch() venv → 8 unités (Pointe-Claire 3, Mascouche 2, Repentigny 2, Saint-Laurent 1 ; 1 460-1 970 $), run.py sync sotramont → found=8 ok (added=0, updated=0, removed=0, 1,4 s) = médiane exacte 8.0, pm2 restart lou-ka-sync, site :8095 → 200.

Simon-Pierre Boucher committed (Oct 30, 2026) parent 3f5c9dc Browse files

1 changed file +21 −17

Unified Split
modified louka/connectors/sotramont.py +21 −17
@@ -52,32 +52,36 @@ class SotramontConnector(BaseConnector):
52 52
53 53 def fetch(self) -> list[Listing]:
54 54 listings: list[Listing] = []
55 − # Hoquets réseau transitoires (vagues DNS du nœud 09-10/09-18, resets
56 − # du VPS) : retry court, puis échec FRANC — un `return []` silencieux
57 − # devenait « 0 trouvé ok » et déclenchait la dérive/stale à tort.
58 − html = ""
55 + # Hoquets transitoires récurrents : GET en échec (vagues DNS du nœud
56 + # 09-10/09-18, resets du VPS) mais AUSSI 200 servi SANS cartes
57 + # (épisodes 10-17 et 10-29) — les deux se retryent, puis échec FRANC
58 + # (jamais de `return []` silencieux → « 0 trouvé ok » à tort).
59 + arts = []
59 60 last_err: Exception | None = None
60 61 for attempt in range(3):
62 + if attempt:
63 + time.sleep(3 * attempt)
61 64 try:
62 65 html = self.get(LIST_URL).text
63 − break
64 66 except Exception as e: # noqa: BLE001 — retry puis erreur franche
65 67 last_err = e
66 − if attempt < 2:
67 − time.sleep(3 * (attempt + 1))
68 + continue
69 + soup = BeautifulSoup(html, "html.parser")
70 + arts = soup.select("article.c--article-project")
71 + if arts:
72 + break
73 + last_err = None
68 74 else:
69 − raise RuntimeError(
70 − f"sotramont : portfolio inaccessible après 3 tentatives "
71 − f"({last_err!r}) — {LIST_URL}")
72 − soup = BeautifulSoup(html, "html.parser")
73 −
74 − arts = soup.select("article.c--article-project")
75 − if not arts:
75 + if last_err is not None:
76 + raise RuntimeError(
77 + f"sotramont : portfolio inaccessible après 3 tentatives "
78 + f"({last_err!r}) — {LIST_URL}")
76 79 # Vrai zéro = cartes présentes mais aucune locative active ;
77 − # AUCUNE carte = gabarit remanié ou page vide → erreur franche.
80 + # AUCUNE carte ×3 = gabarit remanié ou page vide → erreur franche.
78 81 raise RuntimeError(
79 − "sotramont : aucune carte projet dans le portfolio — "
80 − f"site remanié ? — {LIST_URL}")
82 + "sotramont : aucune carte projet dans le portfolio "
83 + "(3 tentatives) — site remanié ? — "
84 + f"{LIST_URL}")
81 85
82 86 seen: set[str] = set()
83 87 for art in arts:
84 88
Menu

Theme