{"record":{"id":"7f21b8f5ccb38be4","repo":"DIYgod/RSSHub","slug":"props-7f21b8","errorCode":null,"errorMessage":"无法解析页面 Props 数据","messagePattern":"无法解析页面 Props 数据","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/comic-fuz/manga.ts","lineNumber":52,"sourceCode":"\n        const response = await ofetch(openUrl, {\n            headers: {\n                'Accept-Language': 'ja,en-US;q=0.9,en;q=0.8',\n            },\n        });\n\n        const $ = load(response);\n        const nextDataText = $('#__NEXT_DATA__').text();\n\n        if (!nextDataText) {\n            throw new Error('无法解析页面数据，请检查漫画 ID 是否正确或页面结构是否变动');\n        }\n\n        const nextData = JSON.parse(nextDataText);\n        const pageProps = nextData.props?.pageProps;\n\n        if (!pageProps) {\n            throw new Error('无法解析页面 Props 数据');\n        }\n\n        const mangaTitle = $('title').text();\n        const mangaAuthor = pageProps.authorships?.map((item: any) => item.author?.authorName).join(', ') || '';\n        const mangaDescription = pageProps.manga?.longDescription || '';\n\n        const chapterGroups = pageProps.chapters || [];\n\n        const allChapters = chapterGroups.flatMap((group: any) => group.chapters || []);\n\n        const items = allChapters.map((chapter: any) => {\n            const pointInfo = chapter.pointConsumption;\n            const amount = pointInfo?.amount || 0;\n\n            let statusText = '';\n            if (pointInfo && Object.keys(pointInfo).length === 0) {\n                statusText = '无料';\n            } else if (amount > 0) {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/comic-fuz/manga.ts#L34-L70","documentation":"After successfully extracting and parsing the __NEXT_DATA__ JSON from comic-fuz, the expected nextData.props.pageProps object is missing. This means Next.js rendered a page with hydration data but the route's data payload (pageProps) was not populated, typically indicating an error or redirect state rendered server-side.","triggerScenarios":"The __NEXT_DATA__ JSON exists and parses, but nextData.props.pageProps is undefined or null. This occurs when the server renders an error boundary page (e.g., manga not found) that still includes __NEXT_DATA__ for framework bootstrapping but without the expected page-level props.","commonSituations":"The manga ID was valid at one point but has been removed or made private; the site's Next.js app routing changed and pageProps is now nested differently (e.g., under a different key); a transient server error caused Next.js to render without props.","solutions":["Log the full nextData object to inspect which props are actually present — the structure may have changed.","Verify the manga ID by visiting the page in a browser and checking the Network tab for the actual pageProps shape.","If the site migrated to Next.js App Router, pageProps may no longer exist — look for a different data embedding pattern.","Add a more specific error message that includes the manga ID to help users self-diagnose."],"exampleFix":"// before\nconst nextData = JSON.parse(nextDataText);\nconst pageProps = nextData.props?.pageProps;\nif (!pageProps) {\n    throw new Error('无法解析页面 Props 数据');\n}\n\n// after — expose available keys for diagnosis\nconst nextData = JSON.parse(nextDataText);\nconst pageProps = nextData.props?.pageProps;\nif (!pageProps) {\n    const availableKeys = Object.keys(nextData.props || {});\n    throw new Error(`pageProps missing in __NEXT_DATA__; available prop keys: ${availableKeys.join(', ')}`);\n}","handlingStrategy":"validation","validationCode":"const nextData = JSON.parse(nextDataText);\nif (!nextData.props?.pageProps) {\n    // Log available structure for diagnosis\n    logger.warn(`pageProps missing. Available keys in nextData: ${Object.keys(nextData).join(', ')}`);\n    throw new Error('pageProps not found in __NEXT_DATA__');\n}","typeGuard":"function hasPageProps(nextData: any): nextData is { props: { pageProps: Record<string, unknown> } } {\n    return nextData != null && typeof nextData === 'object' && nextData.props != null && typeof nextData.props.pageProps === 'object';\n}","tryCatchPattern":"try {\n    const nextData = JSON.parse(nextDataText);\n    const pageProps = nextData.props?.pageProps;\n    if (!pageProps) throw new Error('pageProps missing');\n} catch (e) {\n    if (e instanceof SyntaxError) {\n        throw new Error('Failed to parse __NEXT_DATA__ JSON');\n    }\n    throw e;\n}","preventionTips":["Validate JSON.parse results with try-catch to distinguish parse errors from missing-field errors.","Use optional chaining consistently when traversing nested data from scraped pages.","Log the available structure when validation fails to aid future debugging."],"tags":["scraping","nextjs","parsing","comic-fuz","data-shape"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}