jackwener/OpenCLI · warning · EmptyResultError
No sailings for ${fromCity} to ${toCity} on ${date}
Error message
No sailings for ${fromCity} to ${toCity} on ${date} What it means
This is thrown as an EmptyResultError by the Ctrip ferry CLI when DOM scraping completed successfully but the parsed sailing-rows array is empty. The library distinguishes a genuine 'no sailings' result from a parse failure: if cards were rendered but rows could not be parsed, a different CommandExecutionError is thrown instead, so this error means the page genuinely listed zero sailings for the requested city pair and date.
Source
Thrown at clis/ctrip/ferry.js:72
const searchUrl = buildFerryListUrl(fromCity, toCity, date);
await page.goto(searchUrl);
const waitResult = await page.evaluate(WAIT_FOR_FERRY_JS);
if (waitResult === 'captcha') {
throw new AuthRequiredError('ship.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
}
if (waitResult !== 'content') {
throw new CommandExecutionError(`Ctrip ferry page did not render sailing rows (state=${String(waitResult)})`);
}
const renderedCardCount = await page.evaluate(buildScrollUntilJs('.list-item-parent', limit));
const raw = await page.evaluate(buildFerryExtractJs());
if (!Array.isArray(raw)) {
throw new CommandExecutionError('Ctrip ferry DOM extraction returned malformed rows');
}
if (raw.length === 0) {
if (Number(renderedCardCount) > 0) {
throw new CommandExecutionError('Ctrip ferry rows rendered but parser did not find required sailing anchors');
}
throw new EmptyResultError('ctrip ferry', `No sailings for ${fromCity} to ${toCity} on ${date}`);
}
return raw.slice(0, limit).map((r, i) => ({
rank: i + 1,
shipName: r.shipName,
departureTime: r.departureTime,
fromPort: r.fromPort,
arrivalTime: r.arrivalTime,
toPort: r.toPort,
duration: r.duration,
price: r.price,
status: r.status,
url: searchUrl,
}));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Double-check the city names and confirm the route is actually served by a ferry on that date on the Ctrip site.
- Retry with a nearby date to confirm availability is the issue rather than a route/data problem.
- Catch EmptyResultError in your script and treat it as an expected empty result (exit code EMPTY_RESULT), not a crash.
- If sailings clearly exist on the site, report a possible DOM/parser drift issue to the maintainers.
Example fix
// before
cli(['ferry', '--from', 'Shanghai', '--to', 'Shengsi', '--date', '2026-01-05']);
// after
try {
cli(['ferry', '--from', 'Shanghai', '--to', 'Shengsi', '--date', '2026-01-05']);
} catch (e) {
if (e instanceof EmptyResultError) console.log('no sailings that day');
else throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
const valid = from && to && /^\d{4}-\d{2}-\d{2}$/.test(date) && new Date(date) >= new Date(new Date().toDateString());
if (!valid) throw new Error('check route/city names and use a current-or-future date'); Type guard
function isEmptyResultError(e) { return e && typeof e.code === 'string' && e.code === 'EMPTY_RESULT'; } Try / catch
try { const sailings = await cli(['ferry','--from',from,'--to',to,'--date',date]); return sailings; }
catch (e) { if (e instanceof EmptyResultError || e.code === 'EMPTY_RESULT') return []; throw e; } Prevention
- Verify the route and date exist on Ctrip's site before automating it.
- Treat EMPTY_RESULT exit code as an expected outcome in scripts.
- Search a date range instead of a single date when availability is uncertain.
- Keep city names canonical (as Ctrip resolves them) to avoid zero-match searches.
When it happens
Trigger: Running the `ctrip ferry` command with a from/to city pair and date on which Ctrip's ferry search page renders zero sailing cards, and renderedCardCount is 0 (or falsy) so the empty result is legitimate.
Common situations: Searching an off-season date or a route that is suspended; misspelling city names so Ctrip resolves no routes; querying a same-day date after all sailings have departed; picking a route Ctrip does not sell (e.g. ferry vs. bus substituted).
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 coaches for ${fromCity} to ${toCity} on ${date}
- ctrip flight-round
- ctrip search
- No tour packages for "${destination}"
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/8317041d2dad5671.
Report an issue: GitHub.