{"record":{"id":"b2c8712fccac0f1c","repo":"jackwener/OpenCLI","slug":"no-airport-transfers-for-city-airport","errorCode":null,"errorMessage":"No airport transfers for ${city} (${airport})","messagePattern":"No airport transfers for (.+?) \\((.+?)\\)","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/trip/transfer.js","lineNumber":56,"sourceCode":"        'rank',\n        'type',\n        'passengers', 'luggage',\n        'price', 'currency',\n        'url',\n    ],\n    func: async (page, kwargs) => {\n        const city = parseKeyword('city', kwargs.city);\n        const airport = parseIataCode('airport', kwargs.airport);\n        const limit = parseListLimit(kwargs.limit);\n\n        const listUrl = buildTransferListUrl(city, airport);\n        await page.goto(listUrl);\n        const waitResult = await page.evaluate(WAIT_FOR_TRANSFERS_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 === 'empty') {\n            throw new EmptyResultError('trip transfer', `No airport transfers for ${city} (${airport})`);\n        }\n        if (waitResult !== 'content') {\n            throw new CommandExecutionError(`Trip.com transfer listing did not render (state=${String(waitResult)}); check the city and airport code`);\n        }\n        const landedPath = await page.evaluate('location.pathname');\n        if (!/\\/airport-transfers\\/[^/]+\\/airport-[^/]+/i.test(String(landedPath))) {\n            throw new CommandExecutionError(`Trip.com bounced ${city} / ${airport} to the transfer landing; check the city name matches the airport IATA code`);\n        }\n        const raw = await page.evaluate(buildTransferExtractJs());\n        if (!Array.isArray(raw)) {\n            throw new CommandExecutionError('Trip.com transfer DOM extraction returned malformed rows');\n        }\n        if (raw.length === 0) {\n            throw new CommandExecutionError('Trip.com transfer cards rendered but parser did not find required price anchors');\n        }\n        return raw.slice(0, limit).map((r, i) => ({\n            rank: i + 1,\n            type: r.type,","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/trip/transfer.js#L38-L74","documentation":"EmptyResultError thrown when the transfer page probe returns 'empty': Trip.com rendered the airport-transfer flow but found no transfer options for the given city/airport pair. The scraper worked; the data does not exist.","triggerScenarios":"Querying an airport code that has no transfer listings on Trip.com (small regional airports), or a city/IATA mismatch where Trip.com resolves to a location with no transfer inventory.","commonSituations":"Small or secondary airports (e.g. some regional fields) with no bookable transfers; typo'd IATA codes resolving to unexpected cities; markets where Trip.com doesn't sell transfers.","solutions":["Verify the airport has transfer listings on trip.com in a browser","Double-check the IATA code is the intended airport","Try the nearest major airport instead","Treat EmptyResultError as a legitimate empty answer in your tool, not a bug"],"exampleFix":"// before\nconst rows = await getTransfers('XQT'); // bogus code\n// after\nconst rows = await getTransfers('LHR');","handlingStrategy":"try-catch","validationCode":"// only query major airports known to have transfer inventory\nconst noTransfers = new Set(['XQT',' tiny regional codes']);\nif (noTransfers.has(airport)) return [];","typeGuard":"null","tryCatchPattern":"try {\n  const rows = await getTransfers(args);\n} catch (e) {\n  if (e instanceof EmptyResultError) return [];\n  throw e;\n}","preventionTips":["Verify the airport has transfer listings before bulk runs","Validate IATA codes against an airport database","Fall back to the nearest major airport for regional fields","Treat empty results as valid answers"],"tags":["empty-result","trip-com","scraping","no-data"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}