[ka6] fix connecteur bayshore: retry sur réponse searchjobs non-JSON dans la plateforme taleo — le frontal a renvoyé une page HTML statut 200 au lieu du JSON (« Expecting value: line 2 column 1 », constaté 2026-09-09 06h29 sur bayshore, reparti seul), cas couvert par aucun retry existant (ni 5xx ni anti-bot); nouveau _search_page, 3 essais backoff 10-20 s avec ré-amorçage de session, échec explicite avec extrait du corps après 3 essais; sync rejoué: 11 offres (médiane 11.0)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 changed file +22 −2
modified
jobka/connectors/taleo.py
+22 −2
@@ -87,6 +87,27 @@ class TaleoConnector(BaseConnector): | ||
| 87 | 87 | time.sleep(10 * (attempt + 1)) |
| 88 | 88 | raise RuntimeError(f"Taleo 5xx après 3 essais : {last}") |
| 89 | 89 | |
| 90 | + def _search_page(self, url: str, body: dict) -> dict: | |
| 91 | + # Le frontal Taleo renvoie à l'occasion une page HTML avec statut 200 | |
| 92 | + # au lieu du JSON de searchjobs (session expirée ou interstitiel | |
| 93 | + # passager — « Expecting value: line 2 column 1 » constaté le | |
| 94 | + # 2026-09-09 06h29 sur bayshore, reparti seul) : aucun retry existant | |
| 95 | + # ne couvre ce cas (le corps n'est pas un 5xx ni un blocage). On | |
| 96 | + # retente avec backoff en ré-amorçant la session (nouveaux cookies). | |
| 97 | + for attempt in range(3): | |
| 98 | + resp = self._req("post", url, json=body, | |
| 99 | + headers={"tz": "GMT-04:00"}) | |
| 100 | + try: | |
| 101 | + return resp.json() | |
| 102 | + except ValueError: | |
| 103 | + if attempt == 2: | |
| 104 | + snippet = (resp.text or "")[:120].replace("\n", " ") | |
| 105 | + raise RuntimeError( | |
| 106 | + f"taleo {self.HOST}: searchjobs non-JSON après 3 " | |
| 107 | + f"essais (statut {resp.status_code}) : {snippet!r}") | |
| 108 | + time.sleep(10 * (attempt + 1)) | |
| 109 | + self._bootstrap() | |
| 110 | + | |
| 90 | 111 | def _careers_url(self) -> str: |
| 91 | 112 | return f"{self._base}/{self.SECTION}/jobsearch.ftl?lang={self.LANG}" |
| 92 | 113 | |
@@ -154,8 +175,7 @@ class TaleoConnector(BaseConnector): | ||
| 154 | 175 | page = 1 |
| 155 | 176 | seen: set[str] = set() |
| 156 | 177 | while page <= self.max_pages: |
| 157 | − data = self._req("post", url, json={**body_base, "pageNo": page}, | |
| 158 | − headers={"tz": "GMT-04:00"}).json() | |
| 178 | + data = self._search_page(url, {**body_base, "pageNo": page}) | |
| 159 | 179 | reqs = data.get("requisitionList") or [] |
| 160 | 180 | if not reqs and page == 1 and self.LANG != "en": |
| 161 | 181 | # section carrières anglophone seulement : rebasculer en « en » |
| 162 | 182 | |