{"record":{"id":"7c3b165b1b6f1a49","repo":"jackwener/OpenCLI","slug":"toutiao-recommend-returned-malformed-json-error","errorCode":null,"errorMessage":"toutiao recommend returned malformed JSON: ${error?.message || error}","messagePattern":"toutiao recommend returned malformed JSON: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/toutiao/recommend.js","lineNumber":58,"sourceCode":"        try {\n            resp = await fetch(url, {\n                headers: {\n                    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',\n                    Accept: 'application/json',\n                    Referer: 'https://www.toutiao.com/',\n                },\n            });\n        } catch (error) {\n            throw new CommandExecutionError(`toutiao recommend request failed: ${error?.message || error}`);\n        }\n        if (!resp.ok) {\n            throw new CommandExecutionError(`toutiao recommend failed: HTTP ${resp.status}`);\n        }\n        let payload;\n        try {\n            payload = await resp.json();\n        } catch (error) {\n            throw new CommandExecutionError(`toutiao recommend returned malformed JSON: ${error?.message || error}`);\n        }\n        if (payload?.message && payload.message !== 'success') {\n            throw new CommandExecutionError(`toutiao recommend returned message=${payload.message}`);\n        }\n        if (!Array.isArray(payload?.data)) {\n            throw new CommandExecutionError('toutiao recommend returned a non-array data field');\n        }\n        const rows = payload.data.map(mapRecommendRow).filter(Boolean).slice(0, limit);\n        if (rows.length === 0) {\n            throw new EmptyResultError('toutiao recommend', `频道 ${category} 返回空列表。`);\n        }\n        // Re-rank (1..N) after filter so ranks are dense even if upstream had ads.\n        return rows.map((row, idx) => ({ ...row, rank: idx + 1 }));\n    },\n});\n","sourceCodeStart":40,"sourceCodeEnd":74,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/toutiao/recommend.js#L40-L74","documentation":"This CommandExecutionError is thrown when resp.json() fails while parsing the toutiao recommend response — the body was not valid JSON. The parse error message is embedded so developers can see whether it was an unexpected token, empty body, etc.","triggerScenarios":"Calling 'toutiao recommend' when the upstream returns HTML (anti-bot challenge page), an empty body, truncated gzip content, or any non-JSON payload with a 2xx status.","commonSituations":"Upstream serving a CAPTCHA/verification HTML page with status 200; a transparent proxy intercepting and rewriting the response; CDN error pages; response body truncated by network issues.","solutions":["Dump the raw response body (resp.text()) once to see what upstream actually returned — usually it is an HTML block page.","If it is an anti-bot page, add realistic headers/cookies or route through a different IP.","Retry — truncated/corrupt bodies are often transient.","Check whether a proxy or VPN in the path is mangling the response."],"exampleFix":"// before\nawait recommend({ category: 'tech' });\n// after\ntry {\n  await recommend({ category: 'tech' });\n} catch (e) {\n  if (String(e.message).includes('malformed JSON')) {\n    console.error('Upstream returned non-JSON (likely anti-bot page).', e.message);\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await recommend({ category });\n} catch (e) {\n  if (String(e.message).includes('malformed JSON')) {\n    // upstream returned non-JSON (likely anti-bot page); retry or degrade\n    return [];\n  }\n  throw e;\n}","preventionTips":["Inspect the raw body once when this recurs — usually an HTML block page.","Keep request headers realistic to reduce anti-bot interception.","Distinguish this from network errors: a 200 with junk body is an upstream/proxy issue.","Retry transiently; persistent malformed bodies indicate IP blocking."],"tags":["json","parsing","upstream-api","anti-bot"],"backgroundTag":"invalid-json-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}