{"record":{"id":"0dbbc870a43046ed","repo":"xpzouying/xiaohongshu-mcp","slug":"check-login-status-failed","errorCode":null,"errorMessage":"check login status failed","messagePattern":"check login status failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/login.go","lineNumber":29,"sourceCode":"\ntype LoginAction struct {\n\tpage *rod.Page\n}\n\nfunc NewLogin(page *rod.Page) *LoginAction {\n\treturn &LoginAction{page: page}\n}\n\nfunc (a *LoginAction) CheckLoginStatus(ctx context.Context) (bool, error) {\n\t// 加超时保护：只是查登录态的快速检查，不应无限挂（登录扫码的等待在 Login/WaitForLogin 里）\n\tpp := a.page.Context(ctx).Timeout(30 * time.Second)\n\tpp.MustNavigate(\"https://www.xiaohongshu.com/explore\").MustWaitLoad()\n\n\ttime.Sleep(1 * time.Second)\n\n\texists, _, err := pp.Has(`.main-container .user .link-wrapper .channel`)\n\tif err != nil {\n\t\treturn false, errors.Wrap(err, \"check login status failed\")\n\t}\n\n\tif !exists {\n\t\treturn false, errors.Wrap(err, \"login status element not found\")\n\t}\n\n\treturn true, nil\n}\n\n// 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) {","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/login.go#L11-L47","documentation":"CheckLoginStatus navigates the go-rod page to xiaohongshu.com/explore and queries the login-state CSS selector via pp.Has. This error wraps a failure of the Has query itself — a rod/CDP protocol error, page crash, navigation/context timeout, or target closed — as opposed to merely the element being absent. It means the check could not be performed, not that the user is logged out.","triggerScenarios":"Calling CheckLoginStatus when: the passed ctx is already expired or times out within the 30s window; the browser/tab was closed between navigation and query; page navigation failed (MustNavigate panics aside, the DOM query races a crashed renderer); rod's WebSocket connection to the browser dropped.","commonSituations":"Slow network so explore page load exceeds the 30s Timeout; headless browser killed by OOM; caller cancelled the context; xiaohongshu.com unreachable or returning an error page that breaks the expected DOM query.","solutions":["Check the wrapped err for context.DeadlineExceeded / 'target closed' and re-create the page/browser if the target is gone","Increase the timeout or verify the ctx passed in has enough budget for navigate + load + 1s sleep + query","Confirm the browser process is alive and the rod page still valid before calling; retry the check once after re-navigating","Test network access to https://www.xiaohongshu.com/explore from the host"],"exampleFix":"// before\nexists, _, err := pp.Has(`.main-container .user .link-wrapper .channel`)\nif err != nil {\n\treturn false, errors.Wrap(err, \"check login status failed\")\n}\n// after\nexists, _, err := pp.Has(`.main-container .user .link-wrapper .channel`)\nif err != nil {\n\tif errors.Is(ctx.Err(), context.DeadlineExceeded) {\n\t\treturn false, errors.Wrap(err, \"check login status timed out\")\n\t}\n\treturn false, errors.Wrap(err, \"check login status failed\")\n}","handlingStrategy":"retry","validationCode":"// 调用前确认浏览器与页面仍可用\nif page == nil {\n\treturn errors.New(\"page is nil\")\n}\nif _, err := page.Context(ctx).Timeout(3 * time.Second).Eval(`() => document.readyState`); err != nil {\n\treturn fmt.Errorf(\"browser page not alive: %w\", err)\n}","typeGuard":"func isTimeoutErr(err error) bool {\n\treturn errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), \"timeout\") || strings.Contains(err.Error(), \"target closed\")\n}","tryCatchPattern":"loggedIn, err := loginAction.CheckLoginStatus(ctx)\nif err != nil {\n\tif isTimeoutErr(err) {\n\t\t// 浏览器/网络抖动：重建页面后重试一次\n\t\tpage = browser.MustPage(\"https://www.xiaohongshu.com\")\n\t\tloggedIn, err = loginAction.CheckLoginStatus(ctx)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"login check failed: %w\", err)\n\t}\n}","preventionTips":["Pass a ctx with enough budget (navigate + load + sleep + query)","Detect dead browser targets before querying and recreate the page","Add a small retry around browser-driven checks for flaky CDP calls","Keep the browser process memory-healthy to avoid renderer crashes"],"tags":["go","go-rod","browser-automation","timeout","cdp"],"backgroundTag":"browser-context-timeout","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"}