SPB Git

spb/job-ka

Public

[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é)

Simon-Pierre Boucher committed (Sep 4, 2026) parent a2c6823 Browse files

1 changed file +38 −8

Unified Split
modified jobka/connectors/workday.py +38 −8
@@ -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-08-31 8+# Créé : 2026-08-17 Modifié : 2026-09-04
9 # ============================================================================= 9 # =============================================================================
10 """Plateforme Workday. 10 """Plateforme Workday.
11 11
@@ -30,6 +30,8 @@ import os
30 import re 30 import re
31 import time 31 import time
32 32
33+import requests
34+
33 from ..schema import JobPosting, clean_html, is_quebec_location 35 from ..schema import JobPosting, clean_html, is_quebec_location
34 from .base import BaseConnector 36 from .base import BaseConnector
35 37
@@ -55,20 +57,48 @@ class WorkdayConnector(BaseConnector):
55 def _base(self) -> str: 57 def _base(self) -> str:
56 return f"https://{self.TENANT}.{self.HOST}.myworkdayjobs.com" 58 return f"https://{self.TENANT}.{self.HOST}.myworkdayjobs.com"
57 59
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+
58 def _req_json(self, method: str, url: str, **kwargs) -> dict: 75 def _req_json(self, method: str, url: str, **kwargs) -> dict:
59− # Workday renvoie parfois 200 avec un corps vide/HTML (fenêtres de 76+ # Workday renvoie parfois 200 avec un corps vide/HTML, ou 401
60− # maintenance nocturnes ~03 h EDT, constatées les 29 et 31 août 2026 77+ # « system account » (fenêtres de maintenance nocturnes ~02-03 h EDT,
61− # sur de nombreux tenants) : on retente avec backoff avant 78+ # constatées les 29/31 août et 4 sept. 2026) : on retente avec backoff
62− # d'abandonner, et l'erreur finale nomme le statut HTTP + 79+ # avant d'abandonner, et l'erreur finale est explicite pour que
63− # content-type pour que sync_log soit diagnostiquable. 80+ # sync_log soit diagnostiquable.
64− last: ValueError | None = None 81+ last: Exception | None = None
82+ maintenance = False
65 for attempt in range(3): 83 for attempt in range(3):
66− resp = (self.post if method == "post" else self.get)(url, **kwargs) 84+ try:
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
67 try: 93 try:
68 return resp.json() 94 return resp.json()
69 except ValueError as exc: 95 except ValueError as exc:
70 last = exc 96 last = exc
71 time.sleep(10 * (attempt + 1)) 97 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}")
72 raise RuntimeError( 102 raise RuntimeError(
73 f"Workday non-JSON après 3 essais (HTTP {resp.status_code}, " 103 f"Workday non-JSON après 3 essais (HTTP {resp.status_code}, "
74 f"{resp.headers.get('content-type')}) : {last}") 104 f"{resp.headers.get('content-type')}) : {last}")
75 105
Menu

Theme