Revert "[ka6] connecteur shrinerschildrens: maintenance tenant Workday (401 'system account', 2026-09-04 ~02h EDT, portail redirigé vers community.workday.com/maintenance-page) — retry+backoff du 401 de maintenance dans _req_json de la plateforme workday et erreur explicite dans sync_log; autres tenants wd12 non touchés (cabotcorp 4 offres vérifié)"
This reverts commit 540cb825fb63d55d3f28a930a67d9376b5ec7407.
1 changed file +8 −38
modified
jobka/connectors/workday.py
+8 −38
@@ -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-08-31 | ||
| 9 | # ============================================================================= | 9 | # ============================================================================= | ||
| 10 | """Plateforme Workday. | 10 | """Plateforme Workday. | ||
| 11 | 11 | ||||
@@ -30,8 +30,6 @@ import os | |||||
| 30 | import re | 30 | import re | ||
| 31 | import time | 31 | import time | ||
| 32 | 32 | ||||
| 33 | −import requests | ||||
| 34 | − | ||||
| 35 | from ..schema import JobPosting, clean_html, is_quebec_location | 33 | from ..schema import JobPosting, clean_html, is_quebec_location | ||
| 36 | from .base import BaseConnector | 34 | from .base import BaseConnector | ||
| 37 | 35 | ||||
@@ -57,48 +55,20 @@ class WorkdayConnector(BaseConnector): | |||||
| 57 | def _base(self) -> str: | 55 | def _base(self) -> str: | ||
| 58 | return f"https://{self.TENANT}.{self.HOST}.myworkdayjobs.com" | 56 | return f"https://{self.TENANT}.{self.HOST}.myworkdayjobs.com" | ||
| 59 | 57 | ||||
| 60 | − @staticmethod | ||||
| 61 | − def _is_maintenance_401(exc: requests.exceptions.HTTPError) -> bool: | ||||
| 62 | − """401 « Unable to verify credentials for system account » : signature | ||||
| 63 | − d'un tenant en maintenance Workday (le portail carrières redirige alors | ||||
| 64 | − vers community.workday.com/maintenance-page). Constaté le 2026-09-04 | ||||
| 65 | − sur shrinerschildrens.wd12 — les autres tenants du même host restaient | ||||
| 66 | − servis normalement.""" | ||||
| 67 | − resp = exc.response | ||||
| 68 | − if resp is None or resp.status_code != 401: | ||||
| 69 | − return False | ||||
| 70 | − try: | ||||
| 71 | − return "system account" in resp.text.lower() | ||||
| 72 | − except Exception: | ||||
| 73 | − return False | ||||
| 74 | − | ||||
| 75 | def _req_json(self, method: str, url: str, **kwargs) -> dict: | 58 | def _req_json(self, method: str, url: str, **kwargs) -> dict: | ||
| 76 | − # Workday renvoie parfois 200 avec un corps vide/HTML, ou 401 | 59 | + # Workday renvoie parfois 200 avec un corps vide/HTML (fenêtres de | ||
| 77 | − # « system account » (fenêtres de maintenance nocturnes ~02-03 h EDT, | 60 | + # maintenance nocturnes ~03 h EDT, constatées les 29 et 31 août 2026 | ||
| 78 | − # constatées les 29/31 août et 4 sept. 2026) : on retente avec backoff | 61 | + # sur de nombreux tenants) : on retente avec backoff avant | ||
| 79 | − # avant d'abandonner, et l'erreur finale est explicite pour que | 62 | + # d'abandonner, et l'erreur finale nomme le statut HTTP + | ||
| 80 | − # sync_log soit diagnostiquable. | 63 | + # content-type pour que sync_log soit diagnostiquable. | ||
| 81 | − last: Exception | None = None | 64 | + last: ValueError | None = None | ||
| 82 | − maintenance = False | ||||
| 83 | for attempt in range(3): | 65 | for attempt in range(3): | ||
| 84 | − try: | 66 | + resp = (self.post if method == "post" else self.get)(url, **kwargs) | ||
| 85 | − resp = (self.post if method == "post" else self.get)(url, | ||||
| 86 | − **kwargs) | ||||
| 87 | − except requests.exceptions.HTTPError as exc: | ||||
| 88 | − if not self._is_maintenance_401(exc): | ||||
| 89 | − raise | ||||
| 90 | − last, maintenance = exc, True | ||||
| 91 | − time.sleep(10 * (attempt + 1)) | ||||
| 92 | − continue | ||||
| 93 | try: | 67 | try: | ||
| 94 | return resp.json() | 68 | return resp.json() | ||
| 95 | except ValueError as exc: | 69 | except ValueError as exc: | ||
| 96 | last = exc | 70 | last = exc | ||
| 97 | time.sleep(10 * (attempt + 1)) | 71 | time.sleep(10 * (attempt + 1)) | ||
| 98 | − if maintenance: | ||||
| 99 | − raise RuntimeError( | ||||
| 100 | − "Workday : tenant en maintenance (401 system account) après " | ||||
| 101 | − f"3 essais — fenêtre temporaire côté Workday : {last}") | ||||
| 102 | raise RuntimeError( | 72 | raise RuntimeError( | ||
| 103 | f"Workday non-JSON après 3 essais (HTTP {resp.status_code}, " | 73 | f"Workday non-JSON après 3 essais (HTTP {resp.status_code}, " | ||
| 104 | f"{resp.headers.get('content-type')}) : {last}") | 74 | f"{resp.headers.get('content-type')}) : {last}") | ||
| 105 | 75 | ||||