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

  1. Retry the feed after a short wait — transient for deleted/relisted posts.
  2. If a specific post_id consistently fails, the post is gone; the news list will eventually drop it.
  3. Inspect the JSON in the error message to see Miyoushe's actual response (message/retcode).
  4. 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

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.