{"record":{"id":"ffb3110d7987cc5c","repo":"jackwener/OpenCLI","slug":"ctrip-package","errorCode":null,"errorMessage":"ctrip package","messagePattern":"ctrip package","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"info","filePath":"clis/ctrip/package.js","lineNumber":50,"sourceCode":"    columns: [\n        'rank',\n        'title', 'subtitle',\n        'tags', 'score', 'sold', 'reviews',\n        'price',\n        'url',\n    ],\n    func: async (page, kwargs) => {\n        const destination = parsePlaceName('destination', kwargs.destination);\n        const limit = parseListLimit(kwargs.limit);\n\n        const searchUrl = buildPackageListUrl(destination);\n        await page.goto(searchUrl);\n        const waitResult = await page.evaluate(WAIT_FOR_VACATIONS_JS);\n        if (waitResult === 'captcha') {\n            throw new AuthRequiredError('vacations.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');\n        }\n        if (waitResult === 'empty') {\n            throw new EmptyResultError('ctrip package', `No flight-plus-hotel packages for \"${destination}\"`);\n        }\n        if (waitResult !== 'content') {\n            throw new CommandExecutionError(`Ctrip package page did not render package cards (state=${String(waitResult)})`);\n        }\n        const raw = await page.evaluate(buildVacationsExtractJs());\n        if (!Array.isArray(raw)) {\n            throw new CommandExecutionError('Ctrip package DOM extraction returned malformed rows');\n        }\n        if (raw.length === 0) {\n            throw new CommandExecutionError('Ctrip package cards rendered but parser did not find required package anchors');\n        }\n        return raw.slice(0, limit).map((r, i) => ({\n            rank: i + 1,\n            title: r.title,\n            subtitle: r.subtitle,\n            tags: r.tags,\n            score: r.score,\n            sold: r.sold,","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/ctrip/package.js#L32-L68","documentation":"EmptyResultError thrown when the vacations wait script reports state 'empty' — the page rendered successfully but contains no flight-plus-hotel package cards for the requested destination. This is a legitimate no-results signal, distinct from a captcha or render failure, surfaced as EmptyResultError with the destination echoed.","triggerScenarios":"WAIT_FOR_VACATIONS_JS returns 'empty' after loading buildPackageListUrl(destination): the destination has no package inventory (obscure or international destinations, off-season dates), or the destination string is misspelled so Ctrip returns a zero-card results page.","commonSituations":"Searching niche destinations without package products; typo'd destination strings; date ranges where packages are sold out; region-locked inventory not offered to the current IP/locale.","solutions":["Retry with a major destination city name (e.g. 三亚, 厦门) or fix spelling","Adjust travel dates — packages may be unavailable for the chosen period","Confirm the destination on vacations.ctrip.com manually to verify zero inventory","Try from a locale/IP where the inventory is offered"],"exampleFix":"// before\nawait ctrip.package({ destination: 'Sanya ' }); // trailing space/English name may yield empty\n// after\nawait ctrip.package({ destination: '三亚' });","handlingStrategy":"fallback","validationCode":"const dest = String(kwargs.destination ?? '').trim();\nif (!dest) throw new Error('destination is required');\n// prefer major-city names that are known to carry package inventory\nconst KNOWN_PACKAGE_CITIES = ['三亚', '厦门', '丽江', '桂林'];","typeGuard":"const isKnownPackageDestination = (d) => typeof d === 'string' && d.trim().length > 0;","tryCatchPattern":"try {\n  return await ctrip.package({ destination });\n} catch (e) {\n  if (e instanceof EmptyResultError) {\n    return []; // genuine no-results: offer alternate destinations in UI\n  }\n  throw e;\n}","preventionTips":["Use canonical Chinese destination names","Fall back to nearby major cities when a niche destination is empty","Verify inventory manually on vacations.ctrip.com for new destinations","Treat EmptyResultError as a normal UX branch, not a failure"],"tags":["empty-result","search","ctrip","packages"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}