DIYgod/RSSHub · error · Error

article api error

Error message

article api error

What it means

The SCUT (South China University of Technology) JWC news route calls an internal article API and asserts the response with `apiSuccessAssert(data)`, which throws `'article api error'` when `data.success` is falsy. The upstream API returns `{success: true|false, ...}`; a false value typically means the article id was not found, was archived, or the backend rejected the request.

Source

Thrown at lib/routes/scut/jwc/news.ts:34

const getArticleMobileUrlById = (id) => `${baseUrl}/dist/#/detail/index?id=${id}&type=news`;

const generateArticlePubDate = (createDateStr) => {
    const date = new Date(createDateStr);
    date.setHours(8);
    date.setMinutes(0);
    date.setSeconds(0);
    date.setMilliseconds(0);

    return timezone(date, 8);
};

const isRedirectPage = (data) => !!data.link;

const resolveRelativeUrl = (html) => html.replaceAll('src="/', () => `src="${new URL('.', baseUrl).href}`).replaceAll('href="/', () => `href="${new URL('.', baseUrl).href}`);

const apiSuccessAssert = (data) => {
    if (!data.success) {
        throw new Error('article api error');
    }
};

const generateBannerImgHtml = (bannerImageUrl) => (bannerImageUrl ? `<p><img src="${bannerImageUrl}"></p>` : '');

const generateArticleLink = (id) => `<p>链接:<a href="${getArticleUrlById(id)}">电脑版</a>&nbsp;|&nbsp;<a href="${getArticleMobileUrlById(id)}">手机版</a></p>`;

const generateArticleFullText = (data) => generateBannerImgHtml(data.bannerUrl) + resolveRelativeUrl(data.content) + generateArticleLink(data.id);

export const route: Route = {
    path: '/jwc/news',
    categories: ['university'],
    example: '/scut/jwc/news',
    parameters: {},
    features: {
        requireConfig: false,
        requirePuppeteer: false,
        antiCrawler: true,

View on GitHub (pinned to bed535e087)

Solutions

  1. Retry the route after a short interval — transient upstream failures often clear.
  2. If the error is persistent, the upstream API shape may have changed; inspect the actual response body to see whether `success` was renamed or moved.
  3. Defensively, the handler could skip items with `success===false` instead of throwing, but that requires a code change in lib/routes/scut/jwc/news.ts.

Example fix

// before
const apiSuccessAssert = (data) => {
    if (!data.success) {
        throw new Error('article api error');
    }
};

// after (skip broken items instead of failing the whole feed)
const isArticleAvailable = (data) => !!data.success;
Defensive patterns

Strategy: try-catch

Validate before calling

const data = await fetchArticle(id);
if (!data?.success) {
    // skip rather than throw
    return null;
}

Type guard

const isArticleSuccess = (d: unknown): boolean =>
    typeof d === 'object' && d !== null && (d as any).success === true;

Try / catch

try {
    await apiSuccessAssert(data);
} catch (e) {
    if (e instanceof Error && e.message === 'article api error') {
        // skip this article, continue the feed
        continue;
    }
    throw e;
}

Prevention

When it happens

Trigger: Looping over article ids fetched from the list endpoint and calling the detail API; one id returns `{success: false}` because it was deleted, restricted, or the API is rate-limiting. The throw breaks the whole feed build, not just that item.

Common situations: Article removed from the official site between list fetch and detail fetch; SCUT enabled auth on certain articles; transient backend error or maintenance window.

Related errors


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