{"record":{"id":"2f57f95dd2a536e6","repo":"DIYgod/RSSHub","slug":"error-2f57f9","errorCode":null,"errorMessage":"成功获取数据对象，但未找到作品基本信息","messagePattern":"成功获取数据对象，但未找到作品基本信息","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/comic-walker/manga.ts","lineNumber":68,"sourceCode":"\n        if (!nextDataText) {\n            throw new Error('无法解析页面 HTML 数据，可能触发了反爬策略或页面结构巨变');\n        }\n\n        const nextData = JSON.parse(nextDataText);\n        const queries = nextData.props?.pageProps?.dehydratedState?.queries || [];\n\n        const workQuery = queries.find((q: any) => q.queryKey?.includes('/api/contents/details/work') || (Array.isArray(q.queryKey) && q.queryKey.some((k: any) => typeof k === 'string' && k.includes('work'))));\n\n        if (!workQuery || !workQuery.state?.data) {\n            throw new Error('无法在 HTML 缓存中提取核心数据对象');\n        }\n\n        const data = workQuery.state.data;\n        const work = data.work;\n\n        if (!work) {\n            throw new Error('成功获取数据对象，但未找到作品基本信息');\n        }\n\n        const mangaTitle = work.title || $('title').text();\n        const mangaAuthor = work.authors?.map((author: any) => author.name).join(', ');\n        const mangaDescription = work.summary || '';\n        const coverImage = work.bookCover || work.thumbnail;\n\n        const firstEpisodes = getEpisodes(data.firstEpisodes);\n        const latestEpisodes = getEpisodes(data.latestEpisodes);\n        const extraEpisodes = getEpisodes(data.episodes);\n\n        const seenCodes = new Set<string>();\n        const allChapters = [...firstEpisodes, ...latestEpisodes, ...extraEpisodes]\n            .filter((ep) => {\n                if (ep?.code && !seenCodes.has(ep.code)) {\n                    seenCodes.add(ep.code);\n                    return true;\n                }","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/comic-walker/manga.ts#L50-L86","documentation":"The dehydrated React Query was found and its state.data was non-null, but state.data.work is missing. This is a shape-level mismatch: the API response object exists but does not contain the expected 'work' property that holds manga metadata (title, authors, summary, cover, episodes).","triggerScenarios":"workQuery.state.data is truthy but data.work is undefined or null. This can happen when the API response embeds work data under a different key, when the response represents an error state (e.g., { error: '...' }), or when the query resolved with partial data.","commonSituations":"The API response schema changed — 'work' was renamed or nested one level deeper; the manga was deleted and the API returns a soft-error object with status but no work field; a different query (e.g., a related-works query) was matched by the loose 'work' substring check and contains unrelated data.","solutions":["Log the full data object to see its actual top-level keys.","Tighten the queryKey matching to avoid accidentally matching a non-work query.","Check if the API now nests work data under a different key (e.g., data.result.work or data.data.work).","Verify the manga ID is valid by checking the API response status."],"exampleFix":"// before\nconst data = workQuery.state.data;\nconst work = data.work;\nif (!work) {\n    throw new Error('成功获取数据对象，但未找到作品基本信息');\n}\n\n// after — expose available keys\nconst data = workQuery.state.data;\nconst work = data.work;\nif (!work) {\n    throw new Error(`Data object missing 'work' key. Available keys: ${Object.keys(data).join(', ')}`);\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function hasWorkData(data: any): data is { work: { title: string; authors: any[]; summary: string } } {\n    return data != null && typeof data === 'object' && typeof data.work === 'object' && data.work != null;\n}","tryCatchPattern":null,"preventionTips":["Tighten the queryKey matching to avoid selecting a non-work query that lacks the work field.","Use a type guard to verify the data shape before accessing nested properties.","Log Object.keys(data) when work is missing to quickly identify renamed fields."],"tags":["scraping","react-query","parsing","comic-walker","data-shape"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}