jackwener/OpenCLI · warning · EmptyResultError
No coaches for ${fromCity} to ${toCity} on ${date}
Error message
No coaches for ${fromCity} to ${toCity} on ${date} What it means
The page loaded fine, no captcha appeared, and the extractor returned an empty array with zero rendered cards — Ctrip genuinely has no bus departures for the requested route/date. The CLI throws EmptyResultError so the caller can distinguish 'no data' from 'scraping failed'.
Source
Thrown at clis/ctrip/bus.js:72
const searchUrl = buildBusListUrl(fromCity, toCity, date);
await page.goto(searchUrl);
const waitResult = await page.evaluate(WAIT_FOR_BUS_JS);
if (waitResult === 'captcha') {
throw new AuthRequiredError('bus.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
}
if (waitResult !== 'content') {
throw new CommandExecutionError(`Ctrip bus page did not render schedule rows (state=${String(waitResult)})`);
}
const renderedCardCount = await page.evaluate(buildScrollUntilJs('.list-item-parent', limit));
const raw = await page.evaluate(buildBusExtractJs());
if (!Array.isArray(raw)) {
throw new CommandExecutionError('Ctrip bus DOM extraction returned malformed rows');
}
if (raw.length === 0) {
if (Number(renderedCardCount) > 0) {
throw new CommandExecutionError('Ctrip bus rows rendered but parser did not find required schedule anchors');
}
throw new EmptyResultError('ctrip bus', `No coaches for ${fromCity} to ${toCity} on ${date}`);
}
return raw.slice(0, limit).map((r, i) => ({
rank: i + 1,
departureTime: r.departureTime,
fromStation: r.fromStation,
toStation: r.toStation,
duration: r.duration,
price: r.price,
status: r.status,
url: searchUrl,
}));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Try a nearby or earlier date within the booking window
- Verify the city pair actually has bus service (try the route on bus.ctrip.com manually)
- Check city name normalization — a wrong alias may resolve to an unintended city
- Treat EmptyResultError as an expected empty response in your automation, not a failure to retry
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try {
rows = await ctripBusList({ from, to, date });
} catch (e) {
if (e instanceof EmptyResultError) {
console.info(`No buses found for ${route} on ${date} — treating as empty, not failure`);
rows = [];
} else {
throw e;
}
} Prevention
- Catch EmptyResultError separately from CommandExecutionError — do not retry empty results
- Validate the route has bus service and the date is within ctrip's booking window
- Check city-name normalization before blaming the data
- Model empty results as a normal outcome in downstream pipelines
When it happens
Trigger: `clis ctrip bus --from X --to Y --date D` where Ctrip's list page renders zero .list-item-parent cards for that city pair and date (e.g. distant future dates, holidays with cancelled service, or routes with no bus service).
Common situations: Querying a route served only by train/plane; asking for a date beyond Ctrip's booking window; typos in city names resolving to small towns without bus routes.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Ctrip attraction links rendered but parser did not find requ
- No cruise departure port matching "${port}" (try a listed se
- No cruises currently departing "${port}"
- No sailings for ${fromCity} to ${toCity} on ${date}
- ctrip flight-round
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4ea92c07b443b792.
Report an issue: GitHub.