DIYgod/RSSHub · error · Error
Failed to parse page data
Error message
Failed to parse page data
What it means
extractInitials() either failed to match the /window\.initials\s*=\s*(\S[\s\S]*?);?$/ regex (throws 'initials not found') or JSON.parse failed on the captured payload. The handler swallows that detail and re-throws a generic 'Failed to parse page data'.
Source
Thrown at lib/routes/xhamster/index.ts:117
}
async function handler(ctx) {
const { creators } = ctx.req.param();
const pageUrl = `https://xhamster.com/creators/${encodeURIComponent(creators)}/newest`;
const response = await got(pageUrl);
const $ = load(response.data);
const initialsRaw = $('#initials-script').text();
if (!initialsRaw) {
throw new Error('Could not locate initials script on page');
}
let initials: Initials;
try {
initials = extractInitials(initialsRaw);
} catch {
throw new Error('Failed to parse page data');
}
const creatorName = initials.infoComponent?.pornstarTop?.name ?? creators;
const videos = initials.trendingVideoSectionComponent?.videoListProps?.videoThumbProps ?? [];
const items = videos.map((video) => ({
title: `${video.title}${video.isUHD ? ' [4K]' : ''}`,
link: video.pageURL,
pubDate: video.created ? parseDate(video.created * 1000) : undefined,
author: creatorName,
description: renderDescription(video),
media: {
content: {
url: video.trailerURL ?? video.pageURL,
type: 'video/mp4',
...(video.duration && { duration: video.duration as unknown as string }),
},
thumbnail: {View on GitHub (pinned to bed535e087)
Solutions
- Inspect the raw #initials-script text from the RSSHub host to see the new format.
- Update the extractInitials regex/parse logic at index.ts:62-68 to match the current serialization.
- Report upstream (maintainer eve2ptp) with a sample of the new script payload.
Example fix
// before
const match = scriptContent.match(/window\.initials\s*=\s*(\S[\s\S]*?);?$/);
// after (tolerate trailing content / type-tagged JSON)
const match = scriptContent.match(/window\.initials\s*=\s*(\{[\s\S]*?\})\s*;?\s*(?:<\/script>)?$/); Defensive patterns
Strategy: type-guard
Validate before calling
// Validate the script payload shape before parsing
const raw = $('#initials-script').text();
if (!/window\.initials\s*=/.test(raw)) {
throw new Error('initials assignment missing — page format changed');
}
if (!raw.includes('{') || !raw.includes('}')) {
throw new Error('initials payload does not look like JSON');
} Type guard
function isXhamsterParseError(e: unknown): boolean {
return e instanceof Error && /Failed to parse page data/i.test(e.message);
} Try / catch
try {
initials = extractInitials(initialsRaw);
} catch (parseErr) {
// Preserve the real reason instead of masking it
throw new Error(`Failed to parse xhamster initials: ${parseErr}`, { cause: parseErr });
} Prevention
- Don't swallow the inner parse error — chain it so diagnosis is possible.
- Make extractInitials tolerant of trailing semicolons/script tags.
- Add a snapshot test of the initials regex against a real payload.
When it happens
Trigger: The #initials-script text exists but its format changed — trailing semicolon handling differs, the assignment was renamed, or the JSON is malformed/truncated — index.ts:114-118.
Common situations: xhamster changed how it serializes window.initials (e.g. now uses a JSON <script type="application/json"> instead), or the page injected extra content after the assignment that breaks the greedy regex.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse __NEXT_DATA__ JSON: ${error instanceof Error
- Could not locate initials script on page
- Invalid Engine Value: ${engine}, please check your config.
- 无法获取最新的 year 和 issue
- Invalid domain
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/7674a2ae20f1f96c.
Report an issue: GitHub.