{"record":{"id":"3881f52a9484d95b","repo":"DIYgod/RSSHub","slug":"details-not-found-for-product-item-product-id","errorCode":null,"errorMessage":"Details not found for product ${item.product_id}","messagePattern":"Details not found for product (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/mi/newproducts.ts","lineNumber":50,"sourceCode":"\nconst getDataItem = (listItem: NewProductItem, detail: NewProductDetailData) =>\n    ({\n        title: listItem.product_name,\n        description: utils.renderNewProduct(listItem, detail),\n        link: `https://m.mi.com/commodity/detail/${listItem.product_id}`,\n        image: listItem.img,\n        pubDate: parseDate(listItem.start_time, 'X'),\n        language: 'zh-CN',\n    }) as DataItem;\n\nasync function handler() {\n    const list = await utils.getNewProductList();\n    const details = await getDetails(list);\n\n    const items: DataItem[] = list.map((item) => {\n        const detail = details.get(item.product_id);\n        if (!detail) {\n            throw new Error(`Details not found for product ${item.product_id}`);\n        }\n        return getDataItem(item, detail);\n    });\n\n    return {\n        title: '小米上新',\n        link: 'https://m.mi.com/',\n        item: items,\n        allowEmpty: true,\n        image: 'https://m.mi.com/static/img/icons/apple-touch-icon-152x152.png',\n        language: 'zh-CN',\n    } as Data;\n}\n","sourceCodeStart":32,"sourceCodeEnd":64,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/mi/newproducts.ts#L32-L64","documentation":"Generic Error thrown when, after fetching the product list and their details in parallel, a product_id from the list has no corresponding entry in the details Map. This is an internal data-integrity failure between the two upstream API calls — the list referenced a product whose detail fetch returned nothing.","triggerScenarios":"utils.getNewProductList() returns items, getDetails(list) builds a Map keyed by product_id, and list.map finds an item whose product_id is not a key in that Map. The details API dropped or failed (silently) for that one product.","commonSituations":"Xiaomi's new-products API briefly returned a product detail that 404'd or returned empty; transient upstream inconsistency during a product launch; the detail-fetch loop swallowed an error for one item; product was delisted between the list and detail calls.","solutions":["Retry the request after a short wait — this is usually a transient upstream inconsistency.","If persistent, report an upstream API change to the route maintainer; the detail endpoint shape may have changed.","As a route-hardening fix, skip products missing details instead of throwing (collect valid items only).","Check Xiaomi's m.mi.com to confirm the product still exists."],"exampleFix":"// before\nconst items = list.map((item) => {\n    const detail = details.get(item.product_id);\n    if (!detail) throw new Error(`Details not found for product ${item.product_id}`);\n    return getDataItem(item, detail);\n});\n\n// after — skip missing details gracefully\nconst items = list.flatMap((item) => {\n    const detail = details.get(item.product_id);\n    return detail ? [getDataItem(item, detail)] : [];\n});","handlingStrategy":"retry","validationCode":"// Pre-check: ensure details Map covers all list ids before mapping\nconst missing = list.filter((i) => !details.has(i.product_id));\nif (missing.length) { /* retry detail fetch for missing, or skip */ }","typeGuard":"function allDetailsPresent(list: {product_id: string}[], details: Map<string, unknown>): boolean {\n    return list.every((i) => details.has(i.product_id));\n}","tryCatchPattern":"try {\n    const detail = details.get(item.product_id);\n    if (!detail) throw new Error(`Details not found for ${item.product_id}`);\n} catch (e) {\n    // transient upstream gap — retry once, else skip","preventionTips":["Make getDetails retry failed items individually.","Skip missing products rather than failing the whole feed.","Log missing ids so maintainers can spot upstream drift."],"tags":["mi","data-integrity","upstream","retry"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}