{"record":{"id":"99923a4e29aaefdb","repo":"jackwener/OpenCLI","slug":"hotel-id-is-required-numeric-id-from-ctrip-hotel","errorCode":null,"errorMessage":"hotel id is required (numeric id from `ctrip hotel-suggest`, e.g. 375539)","messagePattern":"hotel id is required \\(numeric id from `ctrip hotel-suggest`, e\\.g\\. 375539\\)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/ctrip/utils.js","lineNumber":603,"sourceCode":"      return null;\n    };\n    const found = detect();\n    if (found) return resolve(found);\n    const observer = new MutationObserver(() => {\n      const result = detect();\n      if (result) { observer.disconnect(); resolve(result); }\n    });\n    observer.observe(document.documentElement, { childList: true, subtree: true });\n    setTimeout(() => { observer.disconnect(); resolve('timeout'); }, 10000);\n  })\n`;\n\n/* ------------------------- hotel detail (browser SSR) ------------------------- */\n\n/** Validate a numeric Ctrip hotel id (returned by `ctrip hotel-suggest`). */\nexport function parseHotelId(raw) {\n    if (raw === undefined || raw === null || String(raw).trim() === '') {\n        throw new ArgumentError('hotel id is required (numeric id from `ctrip hotel-suggest`, e.g. 375539)');\n    }\n    try {\n        return parseStrictPositiveInteger('id', raw);\n    } catch {\n        throw new ArgumentError(`hotel id must be a positive integer, got ${JSON.stringify(raw)}`);\n    }\n}\n\nexport function buildHotelDetailUrl(hotelId) {\n    return `https://hotels.ctrip.com/hotels/detail/?hotelid=${hotelId}`;\n}\n\n/**\n * Browser-context IIFE that projects the single-hotel profile from\n * `__NEXT_DATA__.props.pageProps.hotelDetailResponse`. Rating sub-scores, hot\n * facilities, and the check-in/out policy are each joined into one string so the\n * profile stays a single flat row. Returns `null` when the SSR block is absent,\n * so the caller raises a typed error instead of surfacing blanks. Room-level","sourceCodeStart":585,"sourceCodeEnd":621,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/ctrip/utils.js#L585-L621","documentation":"parseHotelId requires a numeric Ctrip hotel ID as obtained from `ctrip hotel-suggest` (e.g. 375539). undefined, null, or blank/whitespace-only input raises ArgumentError 'hotel id is required ...'. It fails fast before building the hotel detail URL.","triggerScenarios":"Running a ctrip hotel-detail command without the hotel id argument/flag, or passing an empty string or whitespace-only value.","commonSituations":"Skipping the `ctrip hotel-suggest` lookup step, unset shell variables expanding to empty, or passing a hotel NAME ('Grand Hyatt') instead of the numeric ID.","solutions":["Run `ctrip hotel-suggest <name>` and pass the returned numeric hotel id (e.g. 375539).","Ensure the id value is set and non-blank (check shell variable expansion).","Do not pass hotel names; resolve them to numeric IDs via hotel-suggest first."],"exampleFix":"// before\nctrip hotel-detail --id \"\"\n// after\nctrip hotel-detail --id 375539","handlingStrategy":"validation","validationCode":"if (hotelId === undefined || hotelId === null || String(hotelId).trim() === '') {\n  throw new Error('hotel id is required: run `ctrip hotel-suggest` to get a numeric id');\n}","typeGuard":"const isPresent = (v) => v !== undefined && v !== null && String(v).trim() !== '';","tryCatchPattern":"try {\n  const id = parseHotelId(raw);\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.includes('hotel id is required')) {\n    console.error('Usage: ctrip hotel-detail --id 375539');\n  } else throw e;\n}","preventionTips":["Resolve hotel names to numeric IDs via `ctrip hotel-suggest` before calling detail commands.","Check shell variables are non-empty before flag interpolation.","Never pass hotel names where numeric IDs are expected."],"tags":["cli","validation","argument-error","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}