From f1d647bcb237b0a0ec8fadda7fd56d88a35d5de5 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 8 Mar 2026 14:14:55 +0000 Subject: [PATCH] fix: Robust Cloudflare detection to prevent Playwright frame crashes - src/cloudflare.js: Add try-catch around each locator operation in isCloudflareChallenge - src/cloudflare.js: Add waitForLoadState before checking for Cloudflare - src/cloudflare.js: Remove redundant outer try-catch (unreachable code) - epic-claimer-new.js: Add delay after page.goto before checking Cloudflare - epic-claimer-new.js: Wrap isChallenge() call in try-catch Fixes: TypeError: Cannot read properties of undefined (reading 'childFrames') --- epic-claimer-new.js | 24 ++++++++++++++++-------- src/cloudflare.js | 27 +++++++++++++++++++++------ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/epic-claimer-new.js b/epic-claimer-new.js index f1e3362..86649c8 100644 --- a/epic-claimer-new.js +++ b/epic-claimer-new.js @@ -183,16 +183,24 @@ const ensureLoggedIn = async (page, context) => { if (!cfg.debug) context.setDefaultTimeout(cfg.login_timeout); await page.goto(URL_CLAIM, { waitUntil: 'domcontentloaded' }); - if (await isChallenge()) { - console.warn('Cloudflare challenge detected. Attempting to solve with FlareSolverr...'); - const solved = await solveCloudflareChallenge(); - if (solved) { - await page.goto(URL_CLAIM, { waitUntil: 'domcontentloaded' }); + // Small delay to let page stabilize before checking for Cloudflare + await page.waitForTimeout(1000); + + try { + if (await isChallenge()) { + console.warn('Cloudflare challenge detected. Attempting to solve with FlareSolverr...'); + const solved = await solveCloudflareChallenge(); + if (solved) { + await page.goto(URL_CLAIM, { waitUntil: 'domcontentloaded' }); + continue; + } + await notify('epic-games (new): Cloudflare challenge, please solve manually in browser.'); + await page.waitForTimeout(cfg.login_timeout); continue; } - await notify('epic-games (new): Cloudflare challenge, please solve manually in browser.'); - await page.waitForTimeout(cfg.login_timeout); - continue; + } catch (err) { + console.warn('Error checking Cloudflare challenge:', err.message); + // Continue with login attempt anyway } const logged = await attemptAutoLogin(); diff --git a/src/cloudflare.js b/src/cloudflare.js index 2ee0837..46e2968 100644 --- a/src/cloudflare.js +++ b/src/cloudflare.js @@ -99,29 +99,44 @@ export const solveCloudflare = async (page, url) => { * @returns {Promise} - True if Cloudflare challenge is detected */ export const isCloudflareChallenge = async page => { + // Wait for page to be in a stable state before checking + try { + await page.waitForLoadState('domcontentloaded', { timeout: 5000 }); + } catch { + // Page might still be loading, continue anyway + } + + // Check for Cloudflare iframe - wrap in try-catch to avoid frame race conditions try { - // Check for Cloudflare iframe const cfFrame = page.locator('iframe[title*="Cloudflare"], iframe[src*="challenges"]'); if (await cfFrame.count() > 0) { return true; } + } catch { + // Frame access failed, ignore + } - // Check for Cloudflare text + // Check for Cloudflare text - wrap in try-catch + try { const cfText = page.locator('text=Verify you are human, text=Checking your browser'); if (await cfText.count() > 0) { return true; } + } catch { + // Locator failed, ignore + } - // Check for specific Cloudflare URLs + // Check for specific Cloudflare URLs + try { const url = page.url(); if (url.includes('cloudflare') || url.includes('challenges')) { return true; } - - return false; } catch { - return false; + // URL access failed, ignore } + + return false; }; /**