{"record":{"id":"bcbbe9074fed6ccb","repo":"xpzouying/xiaohongshu-mcp","slug":"footer","errorCode":null,"errorMessage":"查找弹窗 footer 失败","messagePattern":"查找弹窗 footer 失败","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/publish.go","lineNumber":1079,"sourceCode":"\t\t}\n\t\ttime.Sleep(300 * time.Millisecond)\n\t\tif isButtonDisabled(btn) {\n\t\t\treturn errors.New(\"声明原创按钮仍处于禁用状态\")\n\t\t}\n\t}\n\n\tif err := humanize.Click(btn); err != nil {\n\t\treturn errors.Wrap(err, \"点击声明原创按钮失败\")\n\t}\n\tslog.Info(\"已成功点击声明原创按钮\")\n\ttime.Sleep(300 * time.Millisecond)\n\treturn nil\n}\n\nfunc findFooterByText(page *rod.Page, keyword string) (*rod.Element, error) {\n\tfooters, err := page.Elements(\"div.footer\")\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"查找弹窗 footer 失败\")\n\t}\n\tfor _, footer := range footers {\n\t\ttext, err := footer.Text()\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.Contains(text, keyword) {\n\t\t\treturn footer, nil\n\t\t}\n\t}\n\treturn nil, errors.Errorf(\"未找到包含%q的弹窗 footer\", keyword)\n}\n\n// checkFooterCheckbox 勾选 footer 内的自定义 checkbox（未勾选时才点）。\nfunc checkFooterCheckbox(footer *rod.Element) error {\n\tcb, err := footer.Element(\"div.d-checkbox\")\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"未找到须知 checkbox\")","sourceCodeStart":1061,"sourceCodeEnd":1097,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/publish.go#L1061-L1097","documentation":"findFooterByText wraps the error from page.Elements(\"div.footer\") with this message. It means rod failed to execute the selector query itself (page/browser closed, CDP error, evaluation failed), not that footers were missing — that case returns a different Errorf message (see error 212).","triggerScenarios":"page.Elements(\"div.footer\") is called on a page whose browser context is gone: tab closed, navigation destroyed the execution context, or the CDP connection dropped.","commonSituations":"Calling publish flows after the page was navigated away or the browser crashed; timeouts canceling the underlying context mid-query.","solutions":["Check that the page/browser is still alive before calling the publish flow","Re-navigate to the publish page and retry","Verify the rod context isn't already canceled (ctx deadline exceeded)","Look at the wrapped inner error — it carries the actual CDP/rod cause"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if _, err := page.Info(); err != nil {\n    return fmt.Errorf(\"browser page unavailable before publish: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := confirmOriginalDeclaration(page); err != nil {\n    var wrapped *errors.wrapError\n    if errors.As(err, &wrapped) && strings.Contains(wrapped.msg, \"查找弹窗 footer 失败\") {\n        // page/context died: re-navigate and retry once\n    }\n}","preventionTips":["Verify page liveness before each publish step","Avoid closing the tab or browser mid-flow","Set generous context deadlines for the whole publish operation","Recover from navigation by re-running the flow from the publish page"],"tags":["go-rod","selector","page-lifecycle"],"backgroundTag":"rod-page-context-canceled","analyzedSha":"332d196854a9eac0d2b8c2c0e3d0cc43139d724c","analyzedAt":"2026-09-05T22:22:55.988Z","contentChangedAt":"2026-09-05T22:22:55.988Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}