/** * Flock 页面存活判定 — 避免 browser.close 后 locator.count 抛 Target closed */ import type { Locator, Page } from "playwright"; const CLOSED_RE = /Target (page|closed)|has been closed|browser has been closed|Execution context was destroyed/i; export function isFlockPageClosedError(error: unknown): boolean { const msg = error instanceof Error ? error.message : String(error ?? ""); return CLOSED_RE.test(msg); } export function isFlockPageAlive(page: Page | null | undefined): boolean { if (!page) return false; try { return !page.isClosed(); } catch { return false; } } /** 关窗时返回 0,不抛;其它错误仍抛出 */ export async function flockLocatorCount(loc: Locator): Promise { try { const page = typeof (loc as { page?: () => Page }).page === "function" ? (loc as { page: () => Page }).page() : undefined; if (page && !isFlockPageAlive(page)) return 0; return await loc.count(); } catch (error) { if (isFlockPageClosedError(error)) return 0; throw error; } } export function flockPageClosedMessage(step?: string): string { const where = step ? `(${step})` : ""; return ( `BROWSER_CLOSED:浏览器窗口已关闭${where}。` + "常见于有头模式手动关窗、提交后页跳转销毁上下文、或 Worker 重试关窗竞态;请勿手动关窗并重试。" ); }