{"record":{"id":"be7e87daba46f243","repo":"jackwener/OpenCLI","slug":"no-timetable-for-from-to-to-country","errorCode":null,"errorMessage":"No timetable for ${from} to ${to} (${country})","messagePattern":"No timetable for (.+?) to (.+?) \\((.+?)\\)","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/trip/train.js","lineNumber":63,"sourceCode":"        const to = parseKeyword('to', kwargs.to);\n        const country = parseKeyword('country', kwargs.country);\n        const limit = parseListLimit(kwargs.limit);\n\n        const searchUrl = buildTrainRouteUrl(country, from, to);\n        await page.goto(searchUrl);\n        const waitResult = await page.evaluate(WAIT_FOR_TRAINS_JS);\n        if (waitResult === 'captcha') {\n            throw new AuthRequiredError('trip.com', 'Trip.com is asking for a verification; complete it in your browser session and retry');\n        }\n        if (waitResult !== 'content') {\n            throw new CommandExecutionError(`Trip.com train timetable did not render (state=${String(waitResult)}); check the city names and --country`);\n        }\n        const raw = await page.evaluate(buildTrainExtractJs());\n        if (!Array.isArray(raw)) {\n            throw new CommandExecutionError('Trip.com train DOM extraction returned malformed rows');\n        }\n        if (raw.length === 0) {\n            throw new EmptyResultError('trip train', `No timetable for ${from} to ${to} (${country})`);\n        }\n        return raw.slice(0, limit).map((r, i) => ({\n            rank: i + 1,\n            departureTime: r.departureTime,\n            fromStation: r.fromStation,\n            arrivalTime: r.arrivalTime,\n            toStation: r.toStation,\n            duration: r.duration,\n            changes: r.changes,\n            url: searchUrl,\n        }));\n    },\n});\n","sourceCodeStart":45,"sourceCodeEnd":77,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/trip/train.js#L45-L77","documentation":"EmptyResultError thrown when the Trip.com train page rendered correctly and extraction succeeded, but zero train rows were found for the requested from/to/country combination. This is a clean 'no data' signal, not a failure of the scraper.","triggerScenarios":"Querying a route with no direct train service (e.g. London to New York), a date far in the future or in the past with no timetable, or a city pair Trip.com does not index for trains in the given --country.","commonSituations":"Users asking for train times between cities connected only by air; querying yesterday's date; picking regional stations that Trip.com treats as separate cities; non-rail city pairs in markets like the US where Trip.com trains coverage is thin.","solutions":["Verify the route actually has train service on trip.com in a browser","Check the date is within Trip.com's bookable timetable window","Try nearby major stations or adjust --country","Handle EmptyResultError gracefully in the caller instead of retrying"],"exampleFix":"// before\ntry { rows = await getTripTrains({ from, to, country }); }\ncatch (e) { retry(e); }\n// after\ntry { rows = await getTripTrains({ from, to, country }); }\ncatch (e) {\n  if (e instanceof EmptyResultError) return [];\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"// sanity-check the route before calling\nconst railPairs = new Set(['london|paris','paris|rome']);\nif (!railPairs.has(`${from.toLowerCase()}|${to.toLowerCase()}`)) {\n  console.warn(`route ${from}->${to} may have no train service`);\n}","typeGuard":"null","tryCatchPattern":"try {\n  const rows = await getTripTrains(args);\n} catch (e) {\n  if (e instanceof EmptyResultError) return [];\n  throw e;\n}","preventionTips":["Confirm routes have rail service before querying","Use valid/bookable dates (not past, not beyond booking window)","Treat EmptyResultError as data-absent, not a bug","Try major stations for ambiguous city names"],"tags":["empty-result","scraping","trip-com","no-data"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}