From 5ae4ebb55ee13b5ce5419ba1140b9fc08dd44c6d Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 8 Jul 2026 07:24:07 +0000 Subject: [PATCH] Bound ChatGPT DOM extraction time --- src/capture.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/capture.ts b/src/capture.ts index ac214b6..dcc669e 100644 --- a/src/capture.ts +++ b/src/capture.ts @@ -207,6 +207,19 @@ async function waitForCdp(port: number, process: ChildProcess): Promise { throw new Error("Chromium CDP endpoint did not become ready."); } +async function withTimeout(promise: Promise, timeoutMs: number, label: string): Promise { + let timeout: NodeJS.Timeout | undefined; + const timeoutPromise = new Promise((_resolve, reject) => { + timeout = setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs}ms.`)), timeoutMs); + }); + try { + return await Promise.race([promise, timeoutPromise]); + } finally { + if (timeout) clearTimeout(timeout); + promise.catch(() => undefined); + } +} + async function stopProcess(process: ChildProcess): Promise { if (process.exitCode !== null || process.signalCode !== null) return; process.kill("SIGTERM"); @@ -274,7 +287,7 @@ async function extractConversation(sourceUrl: string): Promise undefined); await page.waitForTimeout(1000); - const extracted = await page.evaluate(() => { + const extracted = await withTimeout(page.evaluate(() => { function cleanHtml(root: Element): string { const clone = root.cloneNode(true) as Element; clone.querySelectorAll("script, style, iframe, object, embed, form, button, textarea, input, nav").forEach((node) => node.remove()); @@ -331,7 +344,7 @@ async function extractConversation(sourceUrl: string): Promise