DIYgod/RSSHub · error · MiHoYoOfficialError
mihoyo/bbs/official: getPostContent failed: ${url} - ${JSON.
Error message
mihoyo/bbs/official: getPostContent failed: ${url} - ${JSON.stringify(res)} What it means
MiHoYoOfficialError thrown inside getPostContent when the getPostFull API returns a response whose data.data.post is missing. The route intentionally throws (rather than returning empty) to prevent cache.tryGet from caching an empty item — this preserves correctness so a transient failure can be retried rather than frozen.
Source
Thrown at lib/routes/mihoyo/bbs/official.ts:81
url,
});
const list = response?.data?.data?.list;
return list;
};
const getPostContent = async (row, default_gid = '2') => {
const post = row.post;
const post_id = post.post_id;
const query = new URLSearchParams({
post_id,
}).toString();
const url = `https://bbs-api.miyoushe.com/post/wapi/getPostFull?${query}`;
return await cache.tryGet(url, async () => {
const res = await got(url);
const fullRow = res?.data?.data?.post;
if (!fullRow) {
// throw an error to prevent an empty item from being cached and returned
throw new MiHoYoOfficialError(`mihoyo/bbs/official: getPostContent failed: ${url} - ${JSON.stringify(res)}`);
}
// default_gid should be useless since the above error-throwing line, but just in case
const gid = fullRow?.post?.game_id || default_gid;
const author = fullRow?.user?.nickname || '';
const content = fullRow?.post?.content || '';
const tags = fullRow?.topics?.map((item) => item.name) || [];
const description = renderOfficialDescription(post.has_cover, row.cover_list, content);
return {
// 文章标题
title: post.subject,
// 文章链接
link: `https://www.miyoushe.com/${GAME_SHORT_MAP[gid]}/article/${post_id}`,
// 文章正文
description,
// 文章发布日期
pubDate: parseDate(post.created_at * 1000),
// 文章标签
category: tags,View on GitHub (pinned to bed535e087)
Solutions
- Retry the feed after a short wait — transient for deleted/relisted posts.
- If a specific post_id consistently fails, the post is gone; the news list will eventually drop it.
- Inspect the JSON in the error message to see Miyoushe's actual response (message/retcode).
- If retcode indicates auth, refresh MIHOYO_COOKIE.
Example fix
// before — error includes: getPostContent failed: <url> - {"retcode":-100,...}
// after (route-hardening option) — skip failed posts instead of failing the whole feed
const fullRow = res?.data?.data?.post;
if (!fullRow) return null; // filter nulls out of items
// then: items.filter(Boolean) before returning Defensive patterns
Strategy: try-catch
Validate before calling
// Optional: pre-check post_id format if (!/^[0-9]+$/.test(post_id)) return null; // skip malformed
Type guard
function hasPostFull(res: any): res is { data: { data: { post: object } } } {
return Boolean(res?.data?.data?.post);
} Try / catch
try {
const res = await got(url);
if (!res?.data?.data?.post) throw new MiHoYoOfficialError(`getPostContent failed: ${url}`);
} catch (e) {
// skip this post rather than failing the whole feed Prevention
- Throw inside cache.tryGet so empty results aren't cached (current behavior — keep it).
- Filter failed posts out of the final item list to keep the feed alive.
- Log the retcode from the response for upstream-change diagnosis.
When it happens
Trigger: got(getPostFull?post_id=...) resolves, but res.data.data.post is falsy. The post_id is invalid, the post was deleted, the post is access-restricted, or Miyoushe returned an error envelope with HTTP 200. The full response is JSON-stringified into the message for diagnostics.
Common situations: A news-list item references a post that was later deleted; post is region/account restricted; transient upstream error; API envelope changed so the post field moved.
Related errors
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/cd750eda65979ad1.
Report an issue: GitHub.