{"record":{"id":"d5505a9cf602e5cb","repo":"jackwener/OpenCLI","slug":"ctrip-round-trip-flight-page-did-not-render-flight","errorCode":null,"errorMessage":"Ctrip round-trip flight page did not render flight cards (state=${String(waitResult)})","messagePattern":"Ctrip round-trip flight page did not render flight cards \\(state=(.+?)\\)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/ctrip/flight-round.js","lineNumber":87,"sourceCode":"            throw new ArgumentError(`--from and --to must differ (got ${fromCode})`);\n        }\n        const depart = parseIsoDate('depart', kwargs.depart);\n        const ret = parseIsoDate('return', kwargs.return);\n        if (ret < depart) {\n            throw new ArgumentError(`--return (${ret}) must be on or after --depart (${depart})`);\n        }\n        const limit = parseListLimit(kwargs.limit);\n\n        const searchUrl =\n            `https://flights.ctrip.com/online/list/round-${fromCode.toLowerCase()}-${toCode.toLowerCase()}` +\n            `?depdate=${depart}_${ret}&cabin=Y_S_C_F&adult=1&child=0&infant=0`;\n        await page.goto(searchUrl);\n        const waitResult = await page.evaluate(WAIT_FOR_FLIGHTS_ROUND_JS);\n        if (waitResult === 'captcha') {\n            throw new AuthRequiredError('flights.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');\n        }\n        if (waitResult !== 'content') {\n            throw new CommandExecutionError(`Ctrip round-trip flight page did not render flight cards (state=${String(waitResult)})`);\n        }\n        const renderedCardCount = await page.evaluate(buildScrollUntilJs(ROUND_CARD_SELECTOR, limit));\n        const raw = await page.evaluate(buildFlightExtractJs(ROUND_CARD_SELECTOR, false));\n        if (!Array.isArray(raw)) {\n            throw new CommandExecutionError('Ctrip round-trip flight DOM extraction returned malformed rows');\n        }\n        if (raw.length === 0) {\n            if (Number(renderedCardCount) > 0) {\n                throw new CommandExecutionError('Ctrip round-trip flight cards rendered but parser did not find required flight anchors');\n            }\n            throw new EmptyResultError('ctrip flight-round', `No round-trip flights for ${fromCode}→${toCode} on ${depart} / ${ret}`);\n        }\n        const completeRows = raw\n            .filter((r) => r.departureTime && r.departureAirport && r.arrivalTime && r.arrivalAirport && r.airline)\n            .slice(0, limit)\n            .map((r, i) => ({\n                rank: i + 1,\n                airline: r.airline,","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/ctrip/flight-round.js#L69-L105","documentation":"A CommandExecutionError thrown when the in-page wait script returns something other than 'content' or 'captcha' — i.e. the round-trip flight list page finished waiting without rendering flight cards and without showing a captcha. The message embeds the raw wait state (e.g. 'timeout') so you can tell which wait condition failed.","triggerScenarios":"WAIT_FOR_FLIGHTS_ROUND_JS times out or otherwise fails while waiting for the round-trip flight card selector after page.goto(searchUrl), so waitResult is neither 'captcha' nor 'content'.","commonSituations":"Slow network or heavily loaded Ctrip servers delaying render; Ctrip UI redesign moving/changing the flight card selector; page redirected to an error or risk-control page; regional unavailability of the route page.","solutions":["Retry once — transient slowness often resolves on a second run.","Use --timeout / OPENCLI_BROWSER_COMMAND_TIMEOUT to give the page longer to render.","Open the search URL in a normal browser to see what actually renders (error page? redesign?).","If the page renders but the CLI never finds cards, the card selector likely drifted — report a parser breakage."],"exampleFix":"// before\ncli(['flight-round', '--from','PEK','--to','SHA','--depart',d,'--return',r]);\n// after\nrunWithRetry(() => cli(['flight-round', '--from','PEK','--to','SHA','--depart',d,'--return',r]), { retries: 2, delayMs: 8000 });","handlingStrategy":"retry","validationCode":null,"typeGuard":"function isRenderFailure(e) { return e && String(e.message || '').includes('did not render flight cards'); }","tryCatchPattern":"try { return await runFlightRound(args); }\ncatch (e) {\n  if (isRenderFailure(e)) { await sleep(10000); return await runFlightRound(args); }\n  throw e;\n}","preventionTips":["Retry with backoff; render timeouts are often transient.","Increase --timeout or OPENCLI_BROWSER_COMMAND_TIMEOUT on slow networks.","Spot-check the search URL manually when failures persist.","Keep the library updated for Ctrip UI/selector changes."],"tags":["scraping","timeout","dom-render","ctrip","browser-automation"],"backgroundTag":"page-render-timeout","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}