DIYgod/RSSHub · error · TypeError

TechFlow API returned an invalid newsflash list.

Error message

TechFlow API returned an invalid newsflash list.

What it means

Same guard pattern as the article list, applied to GET /client/newsflashes. After a successful (non-challenge) request, if response.data is not an Array the route rejects it as an invalid newsflash list. Indicates the newsflash endpoint changed its envelope or returned an error object.

Solutions

  1. Log the raw response to determine the new envelope (e.g. response.data.items) and update the ApiListResponse<Newsflash> type and the Array check.
  2. Confirm the endpoint path /client/newsflashes is still correct in the current TechFlow API.
  3. If the feature is removed, retire the route or point it at the replacement endpoint.
  4. Mirror the article-list hardening: accept a nested array before throwing.

Example fix

// before
if (!Array.isArray(response.data)) {
    throw new TypeError('TechFlow API returned an invalid newsflash list.');
}

// after
const list = Array.isArray(response.data) ? response.data : response.data?.items;
if (!Array.isArray(list)) {
    throw new TypeError(`TechFlow API returned an invalid newsflash list: ${JSON.stringify(response).slice(0, 200)}`);
}
Defensive patterns

Strategy: type-guard

Validate before calling

function isNewsflashList(r: unknown): r is { data: unknown[] } {
    return !!r && typeof r === 'object' && Array.isArray((r as any).data);
}

Type guard

function isNewsflashListResponse(r: unknown): r is { data: Newsflash[] } {
    return typeof r === 'object' && r !== null && Array.isArray((r as { data?: unknown }).data);
}

Try / catch

try {
    const response = await requestApi<ApiListResponse<Newsflash>>('/client/newsflashes', link, params);
    return isNewsflashListResponse(response) ? response.data : [];
} catch (e) {
    if (e instanceof TypeError && /invalid newsflash list/.test(e.message)) {
        return []; // graceful degradation
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling GET {apiRoot}/client/newsflashes with page=1 and page_size=limit where the server returns {data: {...}} or {code, msg} instead of {data: [...]}. Common when the newsletter/newsflash feature is toggled off or the endpoint is renamed.

Common situations: TechFlow deprecates or restructures the newsflash endpoint; a temporary outage returns an error JSON object; the newsflash section is gated behind a locale/plan that the request did not satisfy.

Related errors


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

Appendix: source

Thrown at lib/routes/techflowpost/utils.ts:177

            cache.tryGet(`techflowpost:article:${article.id}`, async () => {
                const itemLink = `${rootUrl}/${locale}/article/${article.id}`;
                const detail = await requestApi<ArticleDetailResponse>(`/client/articles/${article.id}`, itemLink);

                return getArticleItem(article, detail.article?.content);
            })
        )
    );
}

async function getNewsflashItems(limit: string | number) {
    const link = `${rootUrl}/${locale}/newsletter`;
    const response = await requestApi<ApiListResponse<Newsflash>>('/client/newsflashes', link, {
        page: 1,
        page_size: limit,
    });

    if (!Array.isArray(response.data)) {
        throw new TypeError('TechFlow API returned an invalid newsflash list.');
    }

    return await Promise.all(
        response.data.map((newsflash) =>
            cache.tryGet(`techflowpost:newsflash:${newsflash.id}`, async () => {
                const itemLink = `${rootUrl}/${locale}/newsletter/${newsflash.id}`;
                const detail = await requestApi<NewsflashDetailResponse>(`/client/newsflashes/${newsflash.id}`, itemLink);

                return getNewsflashItem(newsflash, detail.content);
            })
        )
    );
}

export { getArticleItems, getNewsflashItems, rootUrl };

View on GitHub (pinned to bed535e087)