DIYgod/RSSHub · warning
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#mei-hua-wang-wen-zhang">docs</a>
What it means
Thrown by the Meihua (梅花网) article route (deprecated) when :caty is not a config key. Config maps slugs (e.g. a 'latest' key → article!2 最新, hot → article!3 热门) to Meihua section tokens used in the URL. Miss throws before the JSON scrape.
Source
Thrown at lib/routes-deprecated/meihua/article.js:18
const got = require('@/utils/got');
const cheerio = require('cheerio');
const config = {
latest: {
link: 'article!2',
title: '最新',
},
hot: {
link: 'article!3',
title: '热门',
},
};
module.exports = async (ctx) => {
const cfg = config[ctx.params.caty];
if (!cfg) {
throw new Error('Bad category. See <a href="https://docs.rsshub.app/routes/new-media#mei-hua-wang-wen-zhang">docs</a>');
}
const currentUrl = `https://www.meihua.info/${cfg.link}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const data = JSON.parse(response.data.match(/"compositionStore":(.*?),"detailStore":/)[1]);
const shotList = data.compositionsData.list.map((item) => ({
title: item.title,
link: `https://www.meihua.info/article/${item.compositionId}`,
pubDate: new Date(item.gmtPublish).toUTCString(),
}));
const items = await Promise.all(
shotList.map((item) =>
ctx.cache.tryGet(item.link, async () => {View on GitHub (pinned to bed535e087)
Solutions
- Use a documented slug (e.g. the latest/newest key or hot).
- Read the config map at the top of lib/routes-deprecated/meihua/article.js for exact keys.
- If the throw passes but JSON.parse fails downstream, the site markup changed — report the route.
Example fix
// before GET /meihua/article/hott // typo // after GET /meihua/article/hot // 热门
Defensive patterns
Strategy: validation
Validate before calling
const VALID = ['hot' /* + latest/newest key — see config in lib/routes-deprecated/meihua/article.js */];
if (!VALID.includes(ctx.params.caty)) throw new Error(`Invalid caty. Valid: ${VALID.join(', ')}`); Type guard
const isCaty = (v: string): v is 'hot' => v === 'hot';
Try / catch
try { await fetch(route); }
catch (e) {
if (/Bad category/.test(e.message)) listSlugs();
else if (/JSON.parse/.test(String(e))) reportMarkupChange();
else throw e;
} Prevention
- Distinguish article! tokens from shots! tokens.
- Markup changes break the regex even with a valid slug.
When it happens
Trigger: Request with a :caty not in config; config[ctx.params.caty] is undefined and the throw fires.
Common situations: Slug typo, or Meihua renaming its section tokens (article!2 etc.) so config was pruned. The route then regex-parses compositionStore out of the HTML, so even valid slugs break if the site markup changes.
Related errors
- Bad category. See <a href="https://docs.rsshub.app/routes/ne
- Bad category. See <a href="https://docs.rsshub.app/routes/go
- Bad category. See <a href="https://docs.rsshub.app/routes/go
- Nanjing, Cannot find page
- Bad category. See <a href="https://docs.rsshub.app/routes/go
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/f52ae1b615703d06.
Report an issue: GitHub.