{"record":{"id":"a5311cf6f5a4392d","repo":"xpzouying/xiaohongshu-mcp","slug":"w-a5311c","errorCode":null,"errorMessage":"读取通知列表失败: %w","messagePattern":"读取通知列表失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/notification.go","lineNumber":293,"sourceCode":"const itemTypeNote = \"note_info\"\n\n// from 返回发起这条通知的用户。\nfunc (r rawNotification) from() rawUser {\n\tif r.UserInfo.UserID != \"\" || r.UserInfo.Nickname != \"\" {\n\t\treturn r.UserInfo\n\t}\n\treturn r.User\n}\n\n// readTab 读取指定分区的原始数据，字段映射由结构体承担。\nfunc (n *NotificationAction) readTab(page *rod.Page, tab NotificationTab) (*notificationPayload, error) {\n\tres, err := page.Eval(`(tab) => {\n\t\tconst s = window.__INITIAL_STATE__;\n\t\tconst m = s && s.notification && s.notification.notificationMap;\n\t\treturn m && m[tab] ? JSON.stringify(m[tab]) : \"\";\n\t}`, string(tab))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取通知列表失败: %w\", err)\n\t}\n\n\traw := res.Value.String()\n\tif raw == \"\" {\n\t\treturn nil, fmt.Errorf(\"页面状态里没有分区 %s，可能未登录或页面结构已变化\", tab)\n\t}\n\n\tvar payload notificationPayload\n\tif err := json.Unmarshal([]byte(raw), &payload); err != nil {\n\t\treturn nil, fmt.Errorf(\"解析通知列表失败: %w\", err)\n\t}\n\treturn &payload, nil\n}\n\n// visible 判断一条通知的内容是否仍然正常可见。\nfunc (r rawNotification) visible() bool {\n\tif r.Comment.ID != \"\" && r.Comment.Illegal.Status != \"\" && r.Comment.Illegal.Status != statusNormal {\n\t\treturn false","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/notification.go#L275-L311","documentation":"readTab 执行 page.Eval 从 window.__INITIAL_STATE__.notification.notificationMap 读取分区数据时脚本执行失败：页面上下文变化、导航中或 JS 异常。数据尚未注入的情况走另一个空值分支。","triggerScenarios":"调用 NotificationAction.List / Reply / locate 等最终走 readTab 的接口时，page.Eval 返回 err：页面被导航走、浏览器 tab 已关闭、JS 在 __INITIAL_STATE__ 未定义前抛错、rod 连接中断。","commonSituations":"页面还没渲染完就调用接口；浏览器实例被复用但 tab 已被关闭；小红书前端改版导致注入脚本抛异常；网络抖动导致 CDP 连接失败。","solutions":["确认调用前页面已加载完成（MustWaitLoad / WaitStable 后再调用）","打印 %w 展开的原始 rod 错误，判断是 Eval JS 报错还是连接问题","若为连接/超时问题，重建浏览器或 page 后重试","若页面结构变化导致 JS 抛错，更新 readTab 里的注入脚本选择器"],"exampleFix":"// before\nres, err := page.Eval(`(tab) => { ... }`, string(tab))\nif err != nil { return nil, fmt.Errorf(\"读取通知列表失败: %w\", err) }\n// after\npage = page.Timeout(30 * time.Second)\npage.MustWaitLoad()\nres, err := page.Eval(`(tab) => { ... }`, string(tab))\nif err != nil {\n    log.Printf(\"readTab eval failed: %v\", err)\n    return nil, fmt.Errorf(\"读取通知列表失败: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// 调用前确认浏览器与页面可用\nif page == nil || browser == nil { return errors.New(\"browser/page not initialized\") }\n_ = page.Timeout(30 * time.Second).MustNavigate(\"https://www.xiaohongshu.com/notification\").MustWaitLoad()","typeGuard":null,"tryCatchPattern":"items, err := n.List(ctx)\nvar wrapped *fmt.WrapError\nif errors.As(err, &wrapped) && strings.Contains(err.Error(), \"读取通知列表失败\") {\n    // 重建 page 后重试\n    page = browser.MustPage(notificationURL)\n    items, err = n.List(ctx)\n}","preventionTips":["每次调用前确保页面已 MustWaitLoad 且未被导航走","为 page 设置合理 Timeout，避免默认立即失败","复用浏览器实例时检查 tab 有效性","关注小红书前端改版，及时更新注入脚本"],"tags":["go","rod","browser-automation","javascript-eval"],"backgroundTag":"browser-eval-failed","analyzedSha":"332d196854a9eac0d2b8c2c0e3d0cc43139d724c","analyzedAt":"2026-09-05T22:22:55.988Z","contentChangedAt":"2026-09-05T22:22:55.988Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}