DIYgod/RSSHub · warning · InvalidParameterError

Bad category. See <a href="https://docs.rsshub.app/routes/ne

Error message

Bad category. See <a href="https://docs.rsshub.app/routes/new-media#wang-yi-xin-wen-pai-hang-bang">docs</a>

What it means

Thrown by the active (non-deprecated) NetEase 163 news rank route when :category is not a config key. Valid categories: whole, news, entertainment, sports, money, tech, auto, lady, house, game, travel, edu. Unlike the deprecated routes, this throws InvalidParameterError (an HTTP-400-mapping error type) and additionally validates the (category,type,time) combination for allowed time ranges.

Source

Thrown at lib/routes/163/news/rank.ts:124

而所有分类(包括全站)的 **跟贴榜** 的统计时间皆仅包含 “24 小时”、“本周”、“本月”。即可用的\`time\`参数为\`day\`、\`week\`、\`month\`。
:::

新闻分类:

| 全站  | 新闻 | 娱乐          | 体育   | 财经  | 科技 | 汽车 | 女人 | 房产  | 游戏 | 旅游   | 教育 |
| ----- | ---- | ------------- | ------ | ----- | ---- | ---- | ---- | ----- | ---- | ------ | ---- |
| whole | news | entertainment | sports | money | tech | auto | lady | house | game | travel | edu  |`,
};

async function handler(ctx) {
    const category = ctx.req.param('category') || 'whole';
    const type = ctx.req.param('type') || 'click';
    const time = ctx.req.param('time') || 'day';

    const cfg = config[category];
    if (!cfg) {
        throw new InvalidParameterError('Bad category. See <a href="https://docs.rsshub.app/routes/new-media#wang-yi-xin-wen-pai-hang-bang">docs</a>');
    }
    if ((category !== 'whole' && type === 'click' && time === 'month') || (category === 'whole' && type === 'click' && time === 'hour') || (type === 'follow' && time === 'hour')) {
        throw new InvalidParameterError('Bad timeRange range. See <a href="https://docs.rsshub.app/routes/new-media#wang-yi-xin-wen-pai-hang-bang">docs</a>');
    }

    const currentUrl = category === 'money' ? cfg.link : `${rootUrl}${cfg.link}`;
    const response = await got({
        method: 'get',
        url: currentUrl,
        responseType: 'buffer',
    });

    const $ = load(iconv.decode(response.data, 'gbk'));

    const list = $('div.tabContents')
        .eq(timeRange[time].index + (category === 'whole' ? (type === 'click' ? -1 : 2) : type === 'click' ? 0 : 2))
        .find('table tbody tr td a')
        .toArray()

View on GitHub (pinned to bed535e087)

Solutions

  1. Use one of the eleven documented category keys (whole, news, entertainment, sports, money, tech, auto, lady, house, game, travel, edu).
  2. Respect the time-range matrix in the route description: whole+click supports day/week/month; non-whole+click supports hour/day/week; follow supports day/week/month.
  3. Set sensible defaults by omitting optional params (category defaults to whole, type to click, time to day).

Example fix

// before
GET /163/news/rank/quan/click/day   // 'quan' not a key
// after
GET /163/news/rank/whole/click/day    // 全站, valid triplet
Defensive patterns

Strategy: validation

Validate before calling

const CATEGORIES = ['whole','news','entertainment','sports','money','tech','auto','lady','house','game','travel','edu'];
const category = ctx.req.param('category') || 'whole';
if (!CATEGORIES.includes(category)) throw new Error(`Bad category '${category}'. Valid: ${CATEGORIES.join(', ')}`);
// also enforce the (category,type,time) matrix from the route description
const type = ctx.req.param('type') || 'click';
const time = ctx.req.param('time') || 'day';
const bad = (category !== 'whole' && type === 'click' && time === 'month')
  || (category === 'whole' && type === 'click' && time === 'hour')
  || (type === 'follow' && time === 'hour');
if (bad) throw new Error('Unsupported (category,type,time) combination');

Type guard

type Category = 'whole'|'news'|'entertainment'|'sports'|'money'|'tech'|'auto'|'lady'|'house'|'game'|'travel'|'edu';
const isCategory = (v: string): v is Category =>
  ['whole','news','entertainment','sports','money','tech','auto','lady','house','game','travel','edu'].includes(v as Category);

Try / catch

import { InvalidParameterError } from '@/errors/types/invalid-parameter';
try { await handler(ctx); }
catch (e) {
  if (e instanceof InvalidParameterError) return respond400(e.message); // user error
  throw e;
}

Prevention

When it happens

Trigger: Request to /163/news/rank/<category>/... with a category not in config, OR an unsupported (category,type,time) triplet such as (money,click,hour) for whole or (*,click,month) for non-whole, or (any,follow,hour). The first throw is the 'Bad category' one.

Common situations: Category slug typo; using a Chinese label instead of its english key; or requesting a time range the docs tip explicitly disallows (e.g. whole + click + hour). Because type/time have their own valid sets (click|follow; hour|day|week|month) invalid values there fall through and surface as downstream index errors rather than this message.

Related errors


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