{"record":{"id":"3c66604363ef5466","repo":"DIYgod/RSSHub","slug":"data-source-id-not-found","errorCode":null,"errorMessage":"Data source ID not found","messagePattern":"Data source ID not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"lib/routes/gov/nea/bureau.ts","lineNumber":65,"sourceCode":"    ],\n    name: '司工作进展',\n    maintainers: ['nczitzk', 'pseudoyu'],\n    handler,\n    url: 'www.nea.gov.cn/',\n};\n\nasync function handler(ctx) {\n    const { bureau } = ctx.req.param();\n    const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 35;\n\n    const rootUrl = 'https://www.nea.gov.cn';\n    const link = `${rootUrl}/sjzz/${bureau}/index.htm`;\n    const response = await ofetch(link);\n    const $ = load(response);\n\n    const dataSourceId: string | undefined = $('ul#showData0').attr('data')?.split(/:/).pop();\n    if (!dataSourceId) {\n        throw new Error('Data source ID not found');\n    }\n\n    const jsonUrl = new URL(`ds_${dataSourceId}.json`, link).href;\n    const jsonData: NeaResponse = await ofetch(jsonUrl);\n\n    const list: DataItem[] = jsonData.datasource.slice(0, limit).map((item) => {\n        const title = sanitizeHtml(item.title, { allowedTags: [], allowedAttributes: {} });\n\n        return {\n            title,\n            link: new URL(item.publishUrl, rootUrl).href,\n            pubDate: item.publishTime ? timezone(parseDate(item.publishTime), 8) : undefined,\n            description: item.summary?.trim() || title,\n            author: [...new Set([item.sourceText, item.author, item.editor, item.responsibleEditor].filter(Boolean))].map((author) => ({\n                name: author!,\n            })),\n            category: item.keywords.split(/,/),\n        };","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/gov/nea/bureau.ts#L47-L83","documentation":"Thrown by the NEA (National Energy Administration) bureau route when the HTML element 'ul#showData0' either doesn't exist or has no 'data' attribute, or the data attribute doesn't contain a colon-separated value with an ID at the end. The route parses this data attribute (e.g., 'something:12345') to construct a JSON data source URL (ds_12345.json).","triggerScenarios":"A GET to https://www.nea.gov.cn/sjzz/{bureau}/index.htm returns HTML where ul#showData0 is missing, has no data attribute, or the data attribute format changed. The split(/:/).pop() returns undefined when the data attribute is empty or contains no colon.","commonSituations":"The NEA website was redesigned and the data-loading mechanism changed (e.g., switched from JSON data sources to server-side rendering); the specific bureau page uses a different HTML structure; the bureau code is valid but the page is a redirect or error page.","solutions":["Open https://www.nea.gov.cn/sjzz/{bureau}/index.htm in a browser and inspect ul#showData0 to verify the data attribute still exists","If the data source mechanism changed, reverse-engineer the new data-loading approach (check network requests in DevTools)","Update the selector or data-attribute parsing logic to match the new page structure","Verify the bureau code is valid using the options listed in the route parameters"],"exampleFix":"// before\nconst dataSourceId: string | undefined = $('ul#showData0').attr('data')?.split(/:/).pop();\nif (!dataSourceId) {\n    throw new Error('Data source ID not found');\n}\n\n// after (more defensive parsing with diagnostic)\nconst dataAttr = $('ul#showData0').attr('data');\nconst dataSourceId = dataAttr?.split(/:/).pop();\nif (!dataSourceId) {\n    throw new Error(`Data source ID not found on ${link}. The page structure may have changed. ul#showData0 data attribute: ${dataAttr}`);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Wrap data-source extraction in try-catch with a meaningful fallback\nlet dataSourceId: string | undefined;\ntry {\n    dataSourceId = $('ul#showData0').attr('data')?.split(/:/).pop();\n} catch {\n    // selector or attribute missing\n}\nif (!dataSourceId) {\n    // Fall back to parsing the page differently, or return allowEmpty\n    return { title: $('title').text(), link, item: [], allowEmpty: true };\n}","preventionTips":["Monitor NEA website structure changes regularly","Use resilient parsing with fallback selectors","Add allowEmpty: true when the data source may legitimately be missing","Test routes against the live site periodically"],"tags":["scraper","css-selector","site-redesign","brittle","government"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}