jackwener/OpenCLI · warning · EmptyResultError
No prices returned for train_no=${trainNo} ${fromStation.nam
Error message
No prices returned for train_no=${trainNo} ${fromStation.name} -> ${toStation.name} on ${date} What it means
This EmptyResultError is thrown when the 12306 queryTicketPrice API responds successfully but parsePriceData yields zero price rows for the requested train_no/segment/date — i.e. 12306 has no price data to return. The library raises it instead of returning an empty list so callers can distinguish 'no data' from 'empty table'.
Source
Thrown at clis/12306/price.js:157
const seatTypes = String(kwargs['seat-types'] ?? '').trim() || 'OM9PA1A3A4FWZ';
if (!SEAT_TYPES_RE.test(seatTypes)) {
throw new ArgumentError('--seat-types must contain only 12306 seat letters/digits (A-Z, 0-9)');
}
const stations = await fetchStationBundle();
const fromStation = resolveStation(stations, fromArg);
const toStation = resolveStation(stations, toArg);
if (fromStation.code === toStation.code) {
throw new ArgumentError(`--from and --to must differ; both resolved to ${fromStation.name} (${fromStation.code})`);
}
const cookieHeader = await mintSession();
const stops = await queryStopsForPrice(cookieHeader, trainNo, fromStation.code, toStation.code, date);
const { fromNo, toNo } = pickStationNos(stops, fromStation.code, toStation.code, fromStation.name, toStation.name);
const priceData = await queryPrice(cookieHeader, trainNo, fromNo, toNo, seatTypes, date);
const rows = parsePriceData(priceData);
if (rows.length === 0) {
throw new EmptyResultError(
`No prices returned for train_no=${trainNo} ${fromStation.name} -> ${toStation.name} on ${date}`,
'Try a different seat-types letter set, or check that this train operates on the date.',
);
}
return rows;
},
});
export const __test__ = { parsePriceData, pickStationNos, queryStopsForPrice, queryPrice, SEAT_LETTERS, TRAIN_NO_RE };
View on GitHub (pinned to 49907e53dc)
Solutions
- Retry with a different --seat-types letter set (or omit it to use the default OM9PA1A3A4FWZ).
- Confirm the train operates on the date: run `12306 trains --from ... --to ...` for the same date.
- Pick a date within the 12306 pre-sale window (usually ~15 days ahead).
- Re-fetch train_no via `12306 trains` — internal train_no values are date-specific and can differ.
Example fix
// before 12306 price --train-no 24000000G10L --from 北京南 --to 上海 --date 2024-01-01 --seat-types A9 // after 12306 price --train-no 24000000G10L --from 北京南 --to 上海 --date 2026-09-01 # default seat-types, in-sale date
Defensive patterns
Strategy: fallback
Validate before calling
const d = new Date(date);
if (Number.isNaN(d.getTime()) || d < new Date() || d > Date.now() + 15 * 86400e3) {
console.warn(`date ${date} is in the past or beyond the ~15-day pre-sale window; prices may be empty`);
} Try / catch
try {
rows = await price({ 'train-no': tn, from, to, date });
} catch (e) {
if (e instanceof EmptyResultError && /No prices returned/.test(e.message)) {
// fallback: retry with default seat-types and/or verify the train runs that day
rows = await price({ 'train-no': tn, from, to, date, 'seat-types': 'OM9PA1A3A4FWZ' });
} else throw e;
} Prevention
- Confirm the train operates on the date via `12306 trains` before querying prices.
- Stay within the ~15-day 12306 pre-sale window.
- Re-fetch train_no for the specific date — internal train_no is date-dependent.
- Treat EmptyResultError as 'no data', not a bug; catch it explicitly.
When it happens
Trigger: Querying a train that does not operate on the given date; a train_no/segment combination with no on-sale inventory; a --seat-types letter set that matches no seats on that train; dates beyond the 12306 booking window (~15 days).
Common situations: Querying schedules published but not yet priced; holiday-schedule trains on off days; tickets sold out at every class so the price map is empty; typos in the date (--date 2025-13-40 style issues caught earlier, but a valid wrong date like last year is not).
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
- 上游 hot-board 返回空列表。
- 频道 ${category} 返回空列表。
- No 12306 stations match "${keyword}"
- CoinGecko returned no category data.
- coingecko top
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/aba73f5daf105768.
Report an issue: GitHub.