{"record":{"id":"dd247c84c3f8d826","repo":"jackwener/OpenCLI","slug":"sina-finance-rolling-news-api-returned-malformed-d","errorCode":null,"errorMessage":"Sina Finance rolling news API returned malformed data","messagePattern":"Sina Finance rolling news API returned malformed data","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/sinafinance/rolling-news.js","lineNumber":32,"sourceCode":"    return String(value).padStart(2, '0');\n}\n\nfunction formatRollTimestamp(value) {\n    const seconds = Number(value);\n    if (!Number.isFinite(seconds) || seconds <= 0)\n        return '';\n    // Sina's roll page presents finance news in China Standard Time.\n    const date = new Date(seconds * 1000 + 8 * 60 * 60 * 1000);\n    return `${pad2(date.getUTCMonth() + 1)}-${pad2(date.getUTCDate())} ${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}`;\n}\n\nfunction normalizeRollRows(payload) {\n    if (payload?.result?.status?.code !== 0) {\n        throw new CommandExecutionError(`Sina Finance rolling news API failed: ${payload?.result?.status?.msg || 'unknown status'}`);\n    }\n    const items = payload?.result?.data;\n    if (!Array.isArray(items)) {\n        throw new CommandExecutionError('Sina Finance rolling news API returned malformed data');\n    }\n    if (items.length === 0) {\n        throw new EmptyResultError('sinafinance rolling-news');\n    }\n    return items.map((item, index) => {\n        const title = typeof item?.title === 'string' ? item.title.trim() : '';\n        const url = typeof item?.url === 'string' ? item.url.trim() : '';\n        const date = formatRollTimestamp(item?.ctime);\n        if (!title || !url || !date) {\n            throw new CommandExecutionError(`Sina Finance rolling news API returned malformed row ${index + 1}`);\n        }\n        return {\n            column: '财经',\n            title,\n            date,\n            url,\n        };\n    });","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/sinafinance/rolling-news.js#L14-L50","documentation":"CommandExecutionError thrown by normalizeRollRows when payload.result.data is not an array. The library guards against Sina changing the response shape (or an error page being parsed) so map() doesn't crash on undefined. It indicates the response passed the status check but the data field is missing or of the wrong type.","triggerScenarios":"The rolling news API returns status.code === 0 but result.data is undefined, an object, or null — typically after a Sina API schema change, or an intermediary (proxy/captive portal) injecting content.","commonSituations":"Sina silently upgrading their API and relocating the data array; a corporate proxy returning a rewritten payload with status code 0; caching layers returning stale/different schemas.","solutions":["Log the full raw payload to inspect the actual response shape","Check if Sina changed the API response structure and update the CLI","Bypass proxies/VPN to rule out payload rewriting","Pin/report the issue so the parser is updated to the new schema"],"exampleFix":"// before\nconst items = payload?.result?.data; // now an object {list: [...]}\n// after\nconst items = payload?.result?.data?.list ?? payload?.result?.data;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function hasRollDataArray(payload) {\n  return Array.isArray(payload?.result?.data);\n}","tryCatchPattern":"try {\n  const rows = await cli.rollingNews();\n} catch (err) {\n  if (/returned malformed data/.test(err.message)) {\n    // response shape changed; dump raw payload for diagnosis\n    console.error('Sina rolling news schema changed? Inspect raw payload');\n  }\n  throw err;\n}","preventionTips":["Log raw payloads periodically to detect schema drift early","Pin/monitor the CLI version and update when Sina changes the API","Avoid middleboxes (proxies) that rewrite response bodies","Handle this as a distinct failure class from empty results"],"tags":["schema-change","api","malformed-response"],"backgroundTag":"api-response-schema-mismatch","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}