DIYgod/RSSHub · warning · Error

Douban 返回空数据,可能触发反爬或限频。请稍后重试。

Error message

Douban 返回空数据,可能触发反爬或限频。请稍后重试。

What it means

Thrown by the Douban TV coming-soon route when the API returns a valid response with `subjects` being an empty array. This typically indicates Douban's anti-crawler returned a 200 status with empty/filtered results rather than an explicit error. The message suggests possible rate limiting and advises retrying later.

Source

Thrown at lib/routes/douban/tv/coming.ts:191

                        Accept: 'application/json',
                        'User-Agent': apiClientUa,
                    },
                });
                return response.data as ComingSoonResponse;
            } catch (error) {
                throw buildFetchError(error);
            }
        },
        config.cache.routeExpire,
        false
    )) as ComingSoonResponse;

    if (!Array.isArray(data.subjects)) {
        const details = data.msg || data.message || data.reason;
        throw new Error(`Douban 返回数据结构异常,可能触发反爬或限频。${details ? `上游信息:${details}` : ''}`);
    }
    if (data.subjects.length === 0) {
        throw new Error('Douban 返回空数据,可能触发反爬或限频。请稍后重试。');
    }

    const subscriptionCount = data.count ?? 0;
    const total = data.total ?? 0;
    const sortedSubjects = data.subjects.toSorted((a, b) => {
        if (sortBy === 'time') {
            const timeDiff = getSortTimestamp(a.pubdate) - getSortTimestamp(b.pubdate);
            if (timeDiff !== 0) {
                return timeDiff;
            }
            return getWishCount(b.wish_count) - getWishCount(a.wish_count);
        }
        const wishDiff = getWishCount(b.wish_count) - getWishCount(a.wish_count);
        if (wishDiff !== 0) {
            return wishDiff;
        }
        return 0;
    });

View on GitHub (pinned to bed535e087)

Solutions

  1. Retry after a delay — the cache will eventually be populated by a successful request.
  2. Reduce polling frequency to avoid triggering Douban's soft rate limiter.
  3. If persistent, investigate whether the apiKey has been partially restricted.
Defensive patterns

Strategy: retry

Type guard

function hasNonEmptySubjects(data: unknown): boolean {
    return typeof data === 'object' && data !== null && Array.isArray((data as any).subjects) && (data as any).subjects.length > 0;
}

Try / catch

try {
    const feed = await fetch(`${rsshubUrl}/douban/tv/coming`);
} catch (e) {
    if (e.message.includes('返回空数据')) {
        // Soft rate limit — wait longer and retry
        await new Promise(r => setTimeout(r, 120000));
        return fetch(`${rsshubUrl}/douban/tv/coming`);
    }
    throw e;
}

Prevention

When it happens

Trigger: Douban returns {subjects: [], count: 0} in response to suspected automated traffic; temporary API quirk during high load; the coming-soon list is genuinely empty at that moment (unlikely for TV but possible).

Common situations: Repeated polling triggers soft rate limiting where Douban returns 200 but with no data; the Frodo API returns empty as a stealthy anti-bot measure rather than an error code.

Related errors


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