DIYgod/RSSHub · error · Error

response.error

Error message

response.error

What it means

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.

Source

Thrown at lib/routes/tingtingfm/program.tsx:67

    const apiBaseUrl = 'https://api-v3.tingtingfm.com';
    const mobileBaseUrl = 'https://mobile.tingtingfm.com';

    const params = {
        version: 'h5_6.3.2',
        client: getClientVal(30),
        h_program_id: programId,
    };

    const radioInfo = await cache.tryGet(`tingtingfm:program:${programId}`, async () => {
        // the double slash here and below is not a typo
        const { data: response } = await got.post(`${apiBaseUrl}//broadcast/get_program_v3_8`, {
            searchParams: {
                ...params,
                api_sign: sign(params),
            },
        });
        if (response.errno !== 0) {
            throw new Error(response.error);
        }

        return response.data.info;
    });

    const latestAudio = await cache.tryGet(
        `tingtingfm:audio_list:${programId}`,
        async () => {
            const { data: response } = await got.post(`${apiBaseUrl}//broadcast/get_program_audio_list`, {
                searchParams: {
                    ...params,
                    api_sign: sign(params),
                },
            });
            if (response.errno !== 0) {
                throw new Error(response.error);
            }

View on GitHub (pinned to bed535e087)

Solutions

  1. Verify the programId is valid by opening `https://mobile.tingtingfm.com/v3/program/{programId}` in a browser.
  2. 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.
  3. Clear the cache key `tingtingfm:program:{programId}` to force a fresh API call.
  4. Inspect the actual `response.error` text in logs — it is the upstream message and pinpoints the cause.
Defensive patterns

Strategy: try-catch

Type guard

const isTingtingfmSuccess = (r: unknown): r is { errno: 0; data: { info: unknown } } =>
    !!r && typeof r === 'object' && 'errno' in r && (r as any).errno === 0;

Try / catch

try {
    const feed = await buildTingtingfmFeed(programId);
} catch (e) {
    if (e instanceof Error && /sign|version|invalid/i.test(e.message)) {
        // signing algorithm or API version likely outdated
        console.error('TingtingFM API rejected the signed request:', e.message);
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/ea893bba82adc11d. Report an issue: GitHub.