{"record":{"id":"f8e08bcde37f7f06","repo":"jackwener/OpenCLI","slug":"failed-to-load-booking-com-search-page-err-mes","errorCode":null,"errorMessage":"Failed to load Booking.com search page: ${err?.message || err}","messagePattern":"Failed to load Booking\\.com search page: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/booking/search.js","lineNumber":260,"sourceCode":"    const checkin = normalizeDate(kwargs.checkin, 'checkin');\n    const checkout = normalizeDate(kwargs.checkout, 'checkout');\n    if (checkin >= checkout) {\n      throw new ArgumentError(`checkout (${checkout}) must be after checkin (${checkin})`);\n    }\n    const adults = normalizePositiveInt(kwargs.adults, 2, 'adults', 30);\n    const rooms = normalizePositiveInt(kwargs.rooms, 1, 'rooms', 30);\n    const children = normalizeNonNegativeInt(kwargs.children, 0, 'children', 10);\n    const currency = normalizeCurrency(kwargs.currency);\n    const lang = normalizeLang(kwargs.lang);\n    const limit = normalizePositiveInt(kwargs.limit, 25, 'limit', 100);\n    const offset = normalizeNonNegativeInt(kwargs.offset, 0, 'offset', 1000);\n\n    const url = buildSearchUrl({ destination, checkin, checkout, adults, rooms, children, offset, currency, lang });\n\n    try {\n      await page.goto(url);\n    } catch (err) {\n      throw new CommandExecutionError(`Failed to load Booking.com search page: ${err?.message || err}`);\n    }\n\n    // Booking lazy-loads price cells; wait for at least the first card price to settle.\n    try {\n      await page.wait('selector', '[data-testid=property-card]', { timeoutMs: 20000 });\n    } catch (_) {\n      // selector wait is best-effort — extractor handles empty case explicitly\n    }\n\n    let raw;\n    try {\n      raw = await page.evaluate(EXTRACTOR);\n    } catch (err) {\n      throw new CommandExecutionError(`Failed to extract Booking.com cards: ${err?.message || err}`);\n    }\n\n    if (raw && typeof raw === 'object' && raw.data && raw.session) {\n      raw = raw.data;","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/booking/search.js#L242-L278","documentation":"This CommandExecutionError wraps any failure of page.goto(url) while navigating the automated browser to the constructed Booking.com search URL. The library throws it so the underlying navigation error (timeout, DNS failure, aborted request) is reported with clear context naming the page that failed to load. The original error's message is embedded via err?.message || err.","triggerScenarios":"page.goto(url) throws or rejects: network outage, DNS failure, Booking.com unreachable, navigation timeout, browser/page crashed, or an invalid URL produced by buildSearchUrl (e.g. malformed destination encoding).","commonSituations":"Running in a sandboxed/CI environment with no internet access; corporate proxy blocking booking.com; slow connection exceeding the default navigation timeout; headless browser detected and connection reset; destination string containing characters that break the URL.","solutions":["Check network connectivity and that https://www.booking.com is reachable from the environment.","Retry the command — transient timeouts are common; increase the navigation timeout if available.","Verify the destination parameter is a sane, non-empty, URL-encodable string.","If behind a proxy/firewall, configure the browser/environment proxy settings or whitelist booking.com.","Inspect the embedded err message to distinguish timeout vs DNS vs aborted navigation."],"exampleFix":"// before (flaky network, one attempt)\nawait page.goto(url);\n// after (retry with backoff)\nfor (let i = 0; i < 3; i++) {\n  try { await page.goto(url); break; } catch (e) { await new Promise(r => setTimeout(r, 1000 * (i + 1))); if (i === 2) throw e; }\n}","handlingStrategy":"retry","validationCode":"const reachable = await fetch('https://www.booking.com', { method: 'HEAD' }).then(r => r.ok).catch(() => false);\nif (!reachable) throw new Error('booking.com is not reachable from this environment');","typeGuard":null,"tryCatchPattern":"try {\n  await booking.search(params);\n} catch (e) {\n  if (/Failed to load Booking.com search page/.test(e.message)) {\n    // inspect embedded cause: e.message includes err?.message\n    await new Promise(r => setTimeout(r, 3000));\n    return booking.search(params); // one retry for transient navigation failures\n  }\n  throw e;\n}","preventionTips":["Verify outbound network/DNS from CI containers before running searches.","Configure proxy settings for the automated browser if behind a corporate firewall.","Use generous navigation timeouts on slow connections.","URL-encode the destination parameter before passing it.","Check booking.com status/availability before large batch runs."],"tags":["network","navigation","browser-automation"],"backgroundTag":"page-load-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}