{"record":{"id":"637f9e98ac8ac423","repo":"xpzouying/xiaohongshu-mcp","slug":"read-current-user-state-failed","errorCode":null,"errorMessage":"read current user state failed","messagePattern":"read current user state failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/login.go","lineNumber":57,"sourceCode":"// CurrentUser 当前登录用户的基础信息。\ntype CurrentUser struct {\n\tNickname string `json:\"nickname\"`\n\tUserID   string `json:\"userId\"`\n}\n\n// CurrentUser 从当前页面的 __INITIAL_STATE__ 读取登录用户信息。\n// 需在 CheckLoginStatus 之后调用：复用已加载的 explore 页，不做额外导航。\nfunc (a *LoginAction) CurrentUser(ctx context.Context) (*CurrentUser, error) {\n\tpp := a.page.Context(ctx).Timeout(10 * time.Second)\n\n\tres, err := pp.Eval(`() => {\n\t\tconst u = window.__INITIAL_STATE__ && window.__INITIAL_STATE__.user;\n\t\tconst info = u && u.userInfo && u.userInfo.value !== undefined ? u.userInfo.value : (u && u.userInfo);\n\t\tif (!info || info.guest) return \"\";\n\t\treturn JSON.stringify({nickname: info.nickname, userId: info.userId || info.user_id});\n\t}`)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"read current user state failed\")\n\t}\n\n\traw := res.Value.String()\n\tif raw == \"\" {\n\t\treturn nil, errors.New(\"current user not found in page state\")\n\t}\n\n\tvar user CurrentUser\n\tif err := json.Unmarshal([]byte(raw), &user); err != nil {\n\t\treturn nil, errors.Wrap(err, \"unmarshal current user failed\")\n\t}\n\n\treturn &user, nil\n}\n\nfunc (a *LoginAction) Login(ctx context.Context) error {\n\tpp := a.page.Context(ctx)\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/login.go#L39-L75","documentation":"CurrentUser reads the logged-in user info by running a JS snippet against window.__INITIAL_STATE__ on the already-loaded xiaohongshu explore page. 'read current user state failed' wraps any error returned by rod's Eval — the page.evaluate call itself failed (execution context destroyed, page navigating/closed, timeout of the 10s sub-context, or CDP error), not that the user data is missing (that's a separate 'current user not found in page state' error).","triggerScenarios":"Calling LoginAction.CurrentUser when the page is navigating or was closed/navigated away since CheckLoginStatus; the 10s Timeout(ctx) deadline expires before the eval returns; the browser tab crashed or the CDP connection dropped; the page is on a different origin than explore so the eval hits a destroyed context.","commonSituations":"Calling CurrentUser after a redirect or on a freshly created page without first loading the explore page via CheckLoginStatus; headless runs where a previous step closed the page; a slow network making the 10s deadline fire; xiaohongshu front-end redeploy replacing __INITIAL_STATE__ shape causing eval-time JS exceptions.","solutions":["Ensure the explore page is loaded and stable before calling CurrentUser (call CheckLoginStatus or re-navigate first)","Increase the per-call deadline by passing a ctx with a longer budget, since CurrentUser wraps the page in Timeout(10s)","Re-create or re-navigate the rod.Page if it was closed, then retry CurrentUser once","Check the wrapped rod error: 'execution context destroyed' means navigation raced the eval — add a short sleep or WaitDOMStable before the call"],"exampleFix":"// before\nuser, err := login.CurrentUser(ctx) // page was closed earlier\n// after\npp := page.MustNavigate(\"https://www.xiaohongshu.com/explore\").MustWaitLoad()\nlogin := xiaohongshu.NewLogin(pp)\nuser, err := login.CurrentUser(context.Background()) // fresh page, ample ctx budget","handlingStrategy":"try-catch","validationCode":"if page.IsClosed() { return nil, errors.New(\"page closed before CurrentUser\") }\nif _, err := page.Element(\".main-container .user .link-wrapper .channel\"); err != nil { return nil, errors.New(\"not on logged-in explore page\") }","typeGuard":"func evalOk(res *proto.EvalResponse) bool { return res != nil && !res.Value.Nil() && res.Value.Str() != \"\" }","tryCatchPattern":"user, err := login.CurrentUser(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"context deadline exceeded\") {\n        // retry with fresh page navigation\n    }\n    return fmt.Errorf(\"cannot read current user: %w\", err)\n}","preventionTips":["Always load the explore page (CheckLoginStatus) before CurrentUser","Pass a ctx with a comfortable budget; the library enforces its own 10s cap","Don't navigate or close the page concurrently with CurrentUser","Treat CurrentUser output as best-effort: the site's state shape can change in any release"],"tags":["go","rod","browser-automation","evaluate","timeout"],"backgroundTag":"page-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"}