{"record":{"id":"f62aa44c3a94d7a0","repo":"jackwener/OpenCLI","slug":"no-cruise-departure-port-matching-port-try-a","errorCode":null,"errorMessage":"No cruise departure port matching \"${port}\" (try a listed sea-cruise port like 上海 / 威尼斯 / 罗马)","messagePattern":"No cruise departure port matching \"(.+?)\" \\(try a listed sea-cruise port like 上海 / 威尼斯 / 罗马\\)","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/ctrip/cruise.js","lineNumber":59,"sourceCode":"        'tags', 'price',\n        'url',\n    ],\n    func: async (page, kwargs) => {\n        const port = parsePlaceName('port', kwargs.port);\n        const limit = parseListLimit(kwargs.limit);\n\n        const indexUrl = buildCruiseSearchUrl(PORT_INDEX_CODE);\n        await page.goto(indexUrl);\n        const indexWait = await page.evaluate(WAIT_FOR_CRUISE_JS);\n        if (indexWait === 'captcha') {\n            throw new AuthRequiredError('cruise.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');\n        }\n        if (indexWait !== 'content') {\n            throw new CommandExecutionError(`Ctrip cruise page did not render (state=${String(indexWait)})`);\n        }\n        const portCode = await page.evaluate(buildCruisePortLookupJs(port));\n        if (!portCode) {\n            throw new EmptyResultError('ctrip cruise', `No cruise departure port matching \"${port}\" (try a listed sea-cruise port like 上海 / 威尼斯 / 罗马)`);\n        }\n\n        let searchUrl = indexUrl;\n        if (portCode !== PORT_INDEX_CODE) {\n            searchUrl = buildCruiseSearchUrl(portCode);\n            await page.goto(searchUrl);\n            const portWait = await page.evaluate(WAIT_FOR_CRUISE_JS);\n            if (portWait === 'captcha') {\n                throw new AuthRequiredError('cruise.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');\n            }\n            if (portWait === 'empty') {\n                throw new EmptyResultError('ctrip cruise', `No cruises currently departing \"${port}\"`);\n            }\n            if (portWait !== 'content') {\n                throw new CommandExecutionError(`Ctrip cruise port page did not render (state=${String(portWait)})`);\n            }\n        }\n","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/ctrip/cruise.js#L41-L77","documentation":"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 上海 / 威尼斯 / 罗马.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Use a port name exactly as listed on cruise.ctrip.com (Chinese names like 上海 usually match best)","Try one of the suggested ports: 上海 / 威尼斯 / 罗马, to confirm the flow works, then narrow down","Normalize the port input (trim, correct script/language) before invoking","Check the port list rendered by the CLI/page to discover valid port names"],"exampleFix":"// before\nclis ctrip cruise --port \"Shanghai\"\n// after\nclis ctrip cruise --port \"上海\"","handlingStrategy":"validation","validationCode":"const KNOWN_PORTS = ['上海','威尼斯','罗马'];\nconst normalizedPort = String(port || '').trim();\nif (!KNOWN_PORTS.includes(normalizedPort)) {\n  console.warn(`Port \"${normalizedPort}\" may not be a listed sea-cruise port; try one of: ${KNOWN_PORTS.join(' / ')}`);\n}","typeGuard":"null","tryCatchPattern":"try {\n  cruises = await ctripCruiseList({ port });\n} catch (e) {\n  if (e instanceof EmptyResultError && e.message.includes('departure port')) {\n    console.info('Unknown port — list available ports and pick a listed sea-cruise port');\n    cruises = [];\n  } else {\n    throw e;\n  }\n}","preventionTips":["Use port names exactly as ctrip lists them (Chinese names usually match best)","Trim and normalize the --port value (script, whitespace) before invoking","Test with a known-good port (上海) first to isolate port-name issues","Treat EmptyResultError for ports as a user-input problem, not a scrape failure"],"tags":["empty-result","ctrip","input-validation","no-data"],"backgroundTag":"no-matching-entity-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}