jackwener/OpenCLI · error · EmptyResultError
ctrip hotel-search
Error message
ctrip hotel-search
What it means
CommandExecutionError thrown when the SSR hotel list extracted from the Ctrip search page via EXTRACT_HOTELS_JS is not an array. The library expects page.evaluate to return an array of raw hotel entries; anything else (null, object, string) means the page structure changed or the page did not render the expected SSR data. It is thrown to fail fast instead of crashing later in mapHotelRow.
Source
Thrown at clis/ctrip/hotel-search.js:111
const checkout = parseIsoDate('checkout', kwargs.checkout);
assertCheckinBeforeCheckout(checkin, checkout);
const limit = parseHotelLimit(kwargs.limit);
const url = `https://hotels.ctrip.com/hotels/list?city=${cityId}&checkin=${checkin}&checkout=${checkout}`;
await page.goto(url);
const waitResult = await page.evaluate(WAIT_FOR_SSR_JS);
if (waitResult === 'captcha') {
throw new AuthRequiredError('hotels.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
}
if (waitResult !== 'content') {
throw new CommandExecutionError(`Ctrip hotel-search page did not expose SSR hotel list (state=${String(waitResult)})`);
}
const raw = await page.evaluate(EXTRACT_HOTELS_JS);
if (!Array.isArray(raw)) {
throw new CommandExecutionError('Ctrip hotel-search returned malformed SSR hotel list');
}
if (raw.length === 0) {
throw new EmptyResultError('ctrip hotel-search', `No hotels for city=${cityId} on ${checkin} → ${checkout}`);
}
const rows = raw
.map((entry, i) => mapHotelRow(entry, i))
.filter((row) => row.hotelId && row.name)
.slice(0, limit);
if (rows.length === 0) {
throw new CommandExecutionError('Ctrip hotel-search SSR rows were missing required hotelId/name anchors');
}
return rows;
},
});
export const __test__ = { parseHotelLimit, assertCheckinBeforeCheckout, WAIT_FOR_SSR_JS, EXTRACT_HOTELS_JS };
View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the search; transient interstitials often resolve on retry
- Log the raw page.evaluate output and update EXTRACT_HOTELS_JS to the new SSR data shape
- Verify the page is not showing a captcha and refresh your browser session/cookies
- Update the CLI to the latest version with fixed selectors
Example fix
// before
const raw = await page.evaluate(EXTRACT_HOTELS_JS);
if (!Array.isArray(raw)) {
throw new CommandExecutionError('Ctrip hotel-search returned malformed SSR hotel list');
}
// after
let raw = await page.evaluate(EXTRACT_HOTELS_JS);
if (!Array.isArray(raw)) {
raw = await page.evaluate(EXTRACT_HOTELS_JS_FALLBACK_V2); // alternate selector
if (!Array.isArray(raw)) throw new CommandExecutionError('...');
} Defensive patterns
Strategy: try-catch
Validate before calling
const raw = await page.evaluate(EXTRACT_HOTELS_JS);
if (!Array.isArray(raw)) throw new Error('SSR hotel list is not an array — page shape changed or captcha shown'); Type guard
const isHotelRowArray = (v) => Array.isArray(v) && v.every((e) => e && typeof e === 'object');
Try / catch
try {
const rows = await ctrip.hotelSearch({ cityId, checkin, checkout });
} catch (e) {
if (e instanceof CommandExecutionError && /malformed SSR hotel list/.test(e.message)) {
// retry once, then surface as upstream-structure failure
} else throw e;
} Prevention
- Pin and update the CLI version when Ctrip changes markup
- Pre-check for captcha pages before parsing SSR data
- Log raw evaluate output on failure for fast diagnosis
- Add a retry with backoff for transient interstitials
When it happens
Trigger: page.evaluate(EXTRACT_HOTELS_JS) returns a non-array value after running the Ctrip hotel-search page: Ctrip redesigned its SSR data payload, a captcha/interstitial replaced the hotel list, or the extract script matched no window.__initialState-like object and returned null/undefined.
Common situations: Ctrip front-end update changing the SSR state key; scraping from a region that gets bot-challenged; running an outdated CLI against a new Ctrip page version; transient network issues producing a partial HTML shell.
Related errors
- Ctrip hotel detail page did not expose SSR hotel data (state
- Ctrip is asking for a captcha; complete it in your browser s
- Ctrip place page did not render attraction links for city id
- Ctrip attraction DOM extraction returned malformed rows
- Ctrip attraction links rendered but parser did not find requ
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/84d2ea39ff3f2409.
Report an issue: GitHub.