DIYgod/RSSHub · warning · Error

分类不存在

Error message

分类不存在

What it means

Thrown by the juejin (掘金) category handler as a plain Error ('分类不存在' = 'category does not exist') when the `category` path param's `category_url` is not found in the list returned by getCategoryBrief(). The handler fetches the full category brief list and searches for a matching slug; no match means it cannot resolve the numeric category_id needed for the recommend feed API.

Source

Thrown at lib/routes/juejin/category.ts:39

            source: ['juejin.cn/:category'],
        },
    ],
    name: '分类',
    maintainers: ['DIYgod'],
    handler,
    description: `| 后端    | 前端     | Android | iOS | 人工智能 | 开发工具 | 代码人生 | 阅读    |
| ------- | -------- | ------- | --- | -------- | -------- | -------- | ------- |
| backend | frontend | android | ios | ai       | freebie  | career   | article |`,
};

async function handler(ctx) {
    const category = ctx.req.param('category');

    const idResponse = await getCategoryBrief();

    const cat = idResponse.find((item) => item.category_url === category);
    if (!cat) {
        throw new Error('分类不存在');
    }
    const id = cat.category_id;

    const response = await ofetch('https://api.juejin.cn/recommend_api/v1/article/recommend_cate_feed', {
        method: 'POST',
        body: {
            id_type: 2,
            sort_type: 300,
            cate_id: id,
            cursor: '0',
            limit: 20,
        },
    });

    const list = parseList(response.data);
    const resultItems = await ProcessFeed(list);

    return {

View on GitHub (pinned to bed535e087)

Solutions

  1. Use one of the documented slugs: backend, frontend, android, ios, ai, freebie, career, article
  2. If 掘金 renamed a slug, call getCategoryBrief() and update the route's description table to the new value
  3. Log idResponse (the full brief list) when debugging to see all valid category_url values
  4. Handle the comparison case-insensitively if 掘金's URLs vary by case

Example fix

// before
const cat = idResponse.find((item) => item.category_url === category);
if (!cat) {
    throw new Error('分类不存在');
}
// after
const cat = idResponse.find((item) => item.category_url?.toLowerCase() === category.toLowerCase());
if (!cat) {
    const valid = idResponse.map((i) => i.category_url).filter(Boolean).join(', ');
    throw new Error(`分类不存在: '${category}'. Valid: ${valid}`);
}
Defensive patterns

Strategy: type-guard

Validate before calling

async function categoryExists(slug: string): Promise<boolean> {
  const briefs = await getCategoryBrief();
  return briefs.some((i) => i.category_url === slug);
}
if (!(await categoryExists(category))) {
  return ctx.json({ error: `unknown category '${category}'` }, 400);
}

Type guard

interface JuejinBrief { category_url?: string; category_id?: string }
function findCategory(briefs: JuejinBrief[], slug: string): JuejinBrief | undefined {
  return briefs.find((i) => i.category_url?.toLowerCase() === slug.toLowerCase());
}

Try / catch

try { return await handler(ctx); }
catch (e) {
  if (e instanceof Error && e.message === '分类不存在') {
    return ctx.json({ error: `category '${category}' not found` }, 404);
  }
  throw e;
}

Prevention

When it happens

Trigger: Request to /juejin/category/<slug> where <slug> is not among the category_url values returned by juejin's category-brief endpoint (e.g. a typo like 'front-end' instead of 'frontend', or a slug that was renamed/removed by 掘金).

Common situations: User mistypes the category; 掘金 renames or removes a category slug; new category added upstream but user uses an old/wrong slug; case sensitivity (Backend vs backend).

Related errors


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