{"record":{"id":"07fdb8a429b3faaf","repo":"jackwener/OpenCLI","slug":"parse-error-07fdb8","errorCode":"PARSE_ERROR","errorMessage":"Invalid ZSXQ API response","messagePattern":"Invalid ZSXQ API response","errorType":"error_code","errorClass":"CliError","httpStatus":null,"severity":"error","filePath":"clis/zsxq/utils.js","lineNumber":136,"sourceCode":"}\nexport async function fetchFirstJson(page, paths) {\n    let lastFailure = null;\n    for (const path of paths) {\n        const result = await browserJsonRequest(page, path);\n        if (result.ok) {\n            return result;\n        }\n        lastFailure = result;\n    }\n    if (!lastFailure) {\n        throw new CliError('FETCH_ERROR', 'No candidate endpoint returned JSON', `Checked endpoints: ${paths.join(', ')}`);\n    }\n    throw new CliError('FETCH_ERROR', lastFailure.error || 'Failed to fetch ZSXQ API', `Checked endpoints: ${paths.join(', ')}`);\n}\nexport function unwrapRespData(payload) {\n    const record = asRecord(payload);\n    if (!record) {\n        throw new CliError('PARSE_ERROR', 'Invalid ZSXQ API response');\n    }\n    if (record.succeeded === false) {\n        const code = typeof record.code === 'number' ? String(record.code) : 'API_ERROR';\n        const message = typeof record.info === 'string'\n            ? record.info\n            : typeof record.error === 'string'\n                ? record.error\n                : 'ZSXQ API returned an error';\n        throw new CliError(code, message);\n    }\n    return (record.resp_data ?? record.data ?? payload);\n}\nexport function getTopicsFromResponse(payload) {\n    const data = unwrapRespData(payload);\n    if (Array.isArray(data))\n        return data;\n    return pickArray(data.topics, data.list, data.records, data.items, data.search_result);\n}","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zsxq/utils.js#L118-L154","documentation":"unwrapRespData validates the shape of a ZSXQ API JSON payload before extracting resp_data. If the payload is not a plain object (asRecord returns null), it throws CliError PARSE_ERROR 'Invalid ZSXQ API response'. The library throws this because it cannot safely read succeeded/code/resp_data from a non-object payload.","triggerScenarios":"Calling data() (which routes through unwrapRespData) when the endpoint returned JSON that is not an object — e.g. an array, a string, or null payload from an unexpected response.","commonSituations":"API contract change returning a different JSON envelope; a proxy returning JSON like \"ok\" or [1,2]; a mocked/captured response reused incorrectly; CDN or WAF returning an error page that happens to parse as JSON.","solutions":["Log the raw payload before unwrapping to see the actual response shape","Re-run with a fresh authenticated request — a stale/cached HTML-to-JSON artifact is common","Update the library if ZSXQ changed its response envelope (succeeded/code/resp_data)"],"exampleFix":"// before\nconst data = unwrapRespData(payload);\n// after\nconst record = payload && typeof payload === 'object' && !Array.isArray(payload) ? payload : null;\nif (!record) throw new Error('unexpected payload: ' + JSON.stringify(payload).slice(0, 200));\nconst data = unwrapRespData(record);","handlingStrategy":"type-guard","validationCode":"const isRecord = (p) => !!p && typeof p === 'object' && !Array.isArray(p);\nif (!isRecord(payload)) throw new Error('Non-object ZSXQ payload: ' + JSON.stringify(payload).slice(0, 200));","typeGuard":"function isApiRecord(p) {\n  return typeof p === 'object' && p !== null && !Array.isArray(p);\n}","tryCatchPattern":"try {\n  const data = unwrapRespData(payload);\n} catch (e) {\n  if (e.code === 'PARSE_ERROR') console.error('Unexpected ZSXQ payload shape', payload);\n  else throw e;\n}","preventionTips":["Log raw payloads once when integrating a new endpoint to learn its envelope","Check for proxies/WAFs that replace API JSON with their own JSON bodies","Update parsing assumptions when the API envelope (succeeded/code/resp_data) changes"],"tags":["parse","api","json","schema"],"backgroundTag":"api-response-schema-mismatch","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}