SPB Git

spb/job-ka

Public

[ka6] fix connecteur firststudent: retry avec backoff sur 5xx transitoire dans la plateforme workday — un 500 isolé de l'API CXS (constaté 2026-09-07 18h18 sur firststudent.wd1, reparti seul) faisait échouer tout le sync car raise_for_status dans base.get/post court-circuitait le retry de _req_json (qui ne couvrait que le cas 200 non-JSON); les 4xx restent des échecs immédiats; sync rejoué: 35 offres (médiane 35.0)

Simon-Pierre Boucher committed (Sep 8, 2026) parent 9910480 Browse files

1 changed file +17 −3

Unified Split
modified jobka/connectors/workday.py +17 −3
@@ -5,7 +5,7 @@
5 # Fichier : jobka/connectors/workday.py 5 # Fichier : jobka/connectors/workday.py
6 # Rôle : Classe de plateforme Workday (API JSON publique wday/cxs) — un 6 # Rôle : Classe de plateforme Workday (API JSON publique wday/cxs) — un
7 # employeur = une sous-classe de ~10 lignes (TENANT, HOST, SITE) 7 # employeur = une sous-classe de ~10 lignes (TENANT, HOST, SITE)
8−# Créé : 2026-08-17 Modifié : 2026-09-04 8+# Créé : 2026-08-17 Modifié : 2026-09-07
9 # ============================================================================= 9 # =============================================================================
10 """Plateforme Workday. 10 """Plateforme Workday.
11 11
@@ -68,14 +68,28 @@ class WorkdayConnector(BaseConnector):
68 # sur de nombreux tenants) : on retente avec backoff avant 68 # sur de nombreux tenants) : on retente avec backoff avant
69 # d'abandonner, et l'erreur finale nomme le statut HTTP + 69 # d'abandonner, et l'erreur finale nomme le statut HTTP +
70 # content-type pour que sync_log soit diagnostiquable. 70 # content-type pour que sync_log soit diagnostiquable.
71− last: ValueError | None = None 71+ # Même traitement pour les 5xx transitoires (500 isolé constaté le
72+ # 2026-09-07 sur firststudent.wd1, reparti seul) : raise_for_status
73+ # dans base.get/post court-circuitait le retry et un seul 500 faisait
74+ # échouer tout le sync.
75+ last: Exception | None = None
76+ resp = None
72 for attempt in range(3): 77 for attempt in range(3):
73− resp = (self.post if method == "post" else self.get)(url, **kwargs) 78+ try:
79+ resp = (self.post if method == "post" else self.get)(url, **kwargs)
80+ except requests.HTTPError as exc:
81+ if exc.response is None or exc.response.status_code < 500:
82+ raise
83+ last = exc
84+ time.sleep(10 * (attempt + 1))
85+ continue
74 try: 86 try:
75 return resp.json() 87 return resp.json()
76 except ValueError as exc: 88 except ValueError as exc:
77 last = exc 89 last = exc
78 time.sleep(10 * (attempt + 1)) 90 time.sleep(10 * (attempt + 1))
91+ if resp is None:
92+ raise RuntimeError(f"Workday 5xx après 3 essais : {last}")
79 raise RuntimeError( 93 raise RuntimeError(
80 f"Workday non-JSON après 3 essais (HTTP {resp.status_code}, " 94 f"Workday non-JSON après 3 essais (HTTP {resp.status_code}, "
81 f"{resp.headers.get('content-type')}) : {last}") 95 f"{resp.headers.get('content-type')}) : {last}")
82 96
Menu

Theme