jackwener/OpenCLI · warning · EmptyResultError

No cruise departure port matching "${port}" (try a listed se

Error message

No cruise departure port matching "${port}" (try a listed sea-cruise port like 上海 / 威尼斯 / 罗马)

What it means

After the cruise index renders, buildCruisePortLookupJs searches the page's port list for the requested port. If no matching port code is found, the CLI throws EmptyResultError (not a failure) because the port simply is not one of Ctrip's listed sea-cruise departure ports, suggesting known examples like 上海 / 威尼斯 / 罗马.

Source

Thrown at clis/ctrip/cruise.js:59

        'tags', 'price',
        'url',
    ],
    func: async (page, kwargs) => {
        const port = parsePlaceName('port', kwargs.port);
        const limit = parseListLimit(kwargs.limit);

        const indexUrl = buildCruiseSearchUrl(PORT_INDEX_CODE);
        await page.goto(indexUrl);
        const indexWait = await page.evaluate(WAIT_FOR_CRUISE_JS);
        if (indexWait === 'captcha') {
            throw new AuthRequiredError('cruise.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
        }
        if (indexWait !== 'content') {
            throw new CommandExecutionError(`Ctrip cruise page did not render (state=${String(indexWait)})`);
        }
        const portCode = await page.evaluate(buildCruisePortLookupJs(port));
        if (!portCode) {
            throw new EmptyResultError('ctrip cruise', `No cruise departure port matching "${port}" (try a listed sea-cruise port like 上海 / 威尼斯 / 罗马)`);
        }

        let searchUrl = indexUrl;
        if (portCode !== PORT_INDEX_CODE) {
            searchUrl = buildCruiseSearchUrl(portCode);
            await page.goto(searchUrl);
            const portWait = await page.evaluate(WAIT_FOR_CRUISE_JS);
            if (portWait === 'captcha') {
                throw new AuthRequiredError('cruise.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
            }
            if (portWait === 'empty') {
                throw new EmptyResultError('ctrip cruise', `No cruises currently departing "${port}"`);
            }
            if (portWait !== 'content') {
                throw new CommandExecutionError(`Ctrip cruise port page did not render (state=${String(portWait)})`);
            }
        }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use a port name exactly as listed on cruise.ctrip.com (Chinese names like 上海 usually match best)
  2. Try one of the suggested ports: 上海 / 威尼斯 / 罗马, to confirm the flow works, then narrow down
  3. Normalize the port input (trim, correct script/language) before invoking
  4. Check the port list rendered by the CLI/page to discover valid port names

Example fix

// before
clis ctrip cruise --port "Shanghai"
// after
clis ctrip cruise --port "上海"
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_PORTS = ['上海','威尼斯','罗马'];
const normalizedPort = String(port || '').trim();
if (!KNOWN_PORTS.includes(normalizedPort)) {
  console.warn(`Port "${normalizedPort}" may not be a listed sea-cruise port; try one of: ${KNOWN_PORTS.join(' / ')}`);
}

Type guard

null

Try / catch

try {
  cruises = await ctripCruiseList({ port });
} catch (e) {
  if (e instanceof EmptyResultError && e.message.includes('departure port')) {
    console.info('Unknown port — list available ports and pick a listed sea-cruise port');
    cruises = [];
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: `clis ctrip cruise --port <name>` where the port name does not match any entry in Ctrip's port list returned by buildCruisePortLookupJs — misspelled names, non-cruise ports (river ferries, domestic bus terminals), or names in the wrong language/script.

Common situations: Passing an English name where Ctrip lists Chinese names (or vice versa); querying a river-cruise or ferry port not in the sea-cruise index; typos or extra whitespace in the port argument.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/f62aa44c3a94d7a0. Report an issue: GitHub.