From ccbaff8c5fc63a5e961516299b51f9e2c5531725 Mon Sep 17 00:00:00 2001 From: Mathis Date: Mon, 14 Sep 2026 20:29:02 +0000 Subject: [PATCH] fix(ferndesk): bound curl_cffi timeouts + list_all progress logs After CF 1010 bypass, GHA sync hung ~34m before a 502 with no logs (article/section listing). Use explicit (connect, read) timeouts and emit list_all page progress so runs fail/retry visibly instead of appearing stuck. --- scripts/ferndesk_sync.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/ferndesk_sync.py b/scripts/ferndesk_sync.py index 99d0e1d..99b118f 100755 --- a/scripts/ferndesk_sync.py +++ b/scripts/ferndesk_sync.py @@ -111,7 +111,7 @@ def api(key: str, path: str, method: str = "GET", body: dict | None = None, retr url, headers=headers, data=data, - timeout=90, + timeout=(15, 60), # connect, read — avoid multi-minute hangs impersonate="chrome", ) txt = (resp.text or "")[:400] @@ -168,19 +168,24 @@ def api(key: str, path: str, method: str = "GET", body: dict | None = None, retr def list_all(key: str, path: str) -> list: out: list = [] cursor = None + page_n = 0 while True: + page_n += 1 p = path if cursor: sep = "&" if "?" in path else "?" p = f"{path}{sep}cursor={urllib.parse.quote(cursor)}" + log(f"list_all {path} page={page_n} so_far={len(out)}") page = api(key, p) if isinstance(page, list): + log(f"list_all {path} done count={len(page)} (array)") return page out.extend(page.get("results") or page.get("items") or []) if not page.get("has_more") or not page.get("next_cursor"): break cursor = page["next_cursor"] time.sleep(0.2) + log(f"list_all {path} done count={len(out)}") return out @@ -252,6 +257,7 @@ def discover_pages(docs_root: Path) -> list[dict]: def ensure_section(key: str, name: str) -> dict: + log(f"ensure_section {name!r}") for s in list_all(key, "/sections"): if s.get("name") == name: return s