{"record":{"id":"ea893bba82adc11d","repo":"DIYgod/RSSHub","slug":"response-error","errorCode":null,"errorMessage":"response.error","messagePattern":"response\\.error","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/tingtingfm/program.tsx","lineNumber":67,"sourceCode":"    const apiBaseUrl = 'https://api-v3.tingtingfm.com';\n    const mobileBaseUrl = 'https://mobile.tingtingfm.com';\n\n    const params = {\n        version: 'h5_6.3.2',\n        client: getClientVal(30),\n        h_program_id: programId,\n    };\n\n    const radioInfo = await cache.tryGet(`tingtingfm:program:${programId}`, async () => {\n        // the double slash here and below is not a typo\n        const { data: response } = await got.post(`${apiBaseUrl}//broadcast/get_program_v3_8`, {\n            searchParams: {\n                ...params,\n                api_sign: sign(params),\n            },\n        });\n        if (response.errno !== 0) {\n            throw new Error(response.error);\n        }\n\n        return response.data.info;\n    });\n\n    const latestAudio = await cache.tryGet(\n        `tingtingfm:audio_list:${programId}`,\n        async () => {\n            const { data: response } = await got.post(`${apiBaseUrl}//broadcast/get_program_audio_list`, {\n                searchParams: {\n                    ...params,\n                    api_sign: sign(params),\n                },\n            });\n            if (response.errno !== 0) {\n                throw new Error(response.error);\n            }\n","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/tingtingfm/program.tsx#L49-L85","documentation":"Thrown at lib/routes/tingtingfm/program.tsx:67 inside the cache.tryGet for `get_program_v3_8`. The TingtingFM API uses a custom signing scheme (`sign(params)` + `getClientVal`) and returns `{ errno, error, data }`. When `errno !== 0` the API's own `error` string is re-thrown verbatim. This endpoint fetches the radio/program metadata.","triggerScenarios":"The programId does not exist or was removed; the client signature (`api_sign`) is wrong because the `sign()` algorithm or `getClientVal` version changed; the `version: 'h5_6.3.2'` string is outdated and the API rejects it; rate-limiting returns a non-zero errno with a throttle message.","commonSituations":"TingtingFM app version bump invalidates the signing algorithm; stale cache from a previous successful call masks the issue until expiry; programId copied incorrectly from a share URL.","solutions":["Verify the programId is valid by opening `https://mobile.tingtingfm.com/v3/program/{programId}` in a browser.","If all programIds fail, the signing algorithm in ./utils (`sign` / `getClientVal`) likely changed — capture a live request from the TingtingFM mobile web app and diff the params.","Clear the cache key `tingtingfm:program:{programId}` to force a fresh API call.","Inspect the actual `response.error` text in logs — it is the upstream message and pinpoints the cause."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"const isTingtingfmSuccess = (r: unknown): r is { errno: 0; data: { info: unknown } } =>\n    !!r && typeof r === 'object' && 'errno' in r && (r as any).errno === 0;","tryCatchPattern":"try {\n    const feed = await buildTingtingfmFeed(programId);\n} catch (e) {\n    if (e instanceof Error && /sign|version|invalid/i.test(e.message)) {\n        // signing algorithm or API version likely outdated\n        console.error('TingtingFM API rejected the signed request:', e.message);\n    }\n    throw e;\n}","preventionTips":["Verify programId by opening the TingtingFM program page in a browser before subscribing.","Keep the sign() and getClientVal() utilities in ./utils in sync with the current TingtingFM web app version.","Clear the tingtingfm:program:{id} cache key when debugging to ensure fresh API calls.","Log response.errno numerically to distinguish auth errors from not-found errors."],"tags":["api","network","signing","caching","tingtingfm"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}