{"record":{"id":"7e8af51034db4cc2","repo":"xpzouying/xiaohongshu-mcp","slug":"error-7e8af5","errorCode":null,"errorMessage":"等待商品选择弹窗超时","messagePattern":"等待商品选择弹窗超时","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xiaohongshu/publish.go","lineNumber":1253,"sourceCode":"}\n\n// waitForProductModal 等待商品选择弹窗出现\nfunc waitForProductModal(page *rod.Page) (*rod.Element, error) {\n\tdeadline := time.Now().Add(10 * time.Second)\n\n\tfor time.Now().Before(deadline) {\n\t\tmodal, err := page.Element(\".multi-goods-selector-modal\")\n\t\tif err == nil && modal != nil {\n\t\t\tvisible, _ := modal.Visible()\n\t\t\tif visible {\n\t\t\t\tslog.Info(\"商品选择弹窗已出现\")\n\t\t\t\treturn modal, nil\n\t\t\t}\n\t\t}\n\t\ttime.Sleep(100 * time.Millisecond) // 缩短轮询间隔，更快响应\n\t}\n\n\treturn nil, errors.New(\"等待商品选择弹窗超时\")\n}\n\n// searchAndSelectProduct 搜索并选择商品\nfunc searchAndSelectProduct(ctx context.Context, page *rod.Page, modal *rod.Element, keyword string) error {\n\tslog.Info(\"搜索商品\", \"keyword\", keyword)\n\n\t// 1. 获取搜索框\n\tsearchInput, err := modal.Element(`input[placeholder=\"搜索商品ID 或 商品名称\"]`)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"未找到商品搜索框\")\n\t}\n\n\t// 2. 清空并输入关键词。SelectAllText 走 Eval(this.select())，只改选区、不额外\n\t// 派发事件，暂时保留（换键盘全选要区分 Ctrl/Cmd）。\n\tif err := searchInput.SelectAllText(); err != nil {\n\t\tslog.Warn(\"选择搜索框文本失败\", \"error\", err)\n\t}\n\ttime.Sleep(100 * time.Millisecond)","sourceCodeStart":1235,"sourceCodeEnd":1271,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/xiaohongshu/publish.go#L1235-L1271","documentation":"waitForProductModal 在 10 秒轮询窗口内从未找到可见的 .multi-goods-selector-modal 元素：要么点击商品入口后弹窗未弹出（前端渲染失败），要么网络慢导致弹窗 10s 内未加载完成。","triggerScenarios":"bindProducts → waitForProductModal：在发布页点击'添加商品'按钮后，弹窗选择器在超时窗口内始终匹配不到（弹窗没弹出、DOM 结构变了、页面被风控/跳转到登录、网络慢导致弹窗加载晚于超时）。","commonSituations":"小红书前端改版导致弹窗 class 变化；账号无带货权限或店铺未开通导致点击后无响应；页面未登录或被重定向；低网速下弹窗渲染超过等待上限。","solutions":["先用浏览器手动复现，确认点击'添加商品'后弹窗是否出现及实际 DOM 结构","更新 waitForProductModal 中的弹窗选择器以匹配最新 DOM","确认账号已开通带货/商品权限且处于登录态","增加等待时长或提高轮询前的稳定性（如先等待网络空闲）"],"exampleFix":"// before\nreturn nil, errors.New(\"等待商品选择弹窗超时\")\n// after\n// 使用 rod 内置等待代替手动轮询，超时可配置\nreturn nil, fmt.Errorf(\"等待商品选择弹窗超时 (waited %s)\", timeout)","handlingStrategy":"try-catch","validationCode":"// 调用前确认登录态与页面\nu := page.MustInfo().URL\nif strings.Contains(u, \"login\") { return errors.New(\"未登录或被重定向\") }","typeGuard":null,"tryCatchPattern":"if err := bindProducts(page, products); err != nil {\n\tif strings.Contains(err.Error(), \"等待商品选择弹窗超时\") {\n\t\tpage.MustScreenshot(\"product-modal-timeout.png\")\n\t\treturn skipProductBinding\n\t}\n\treturn err\n}","preventionTips":["升级前先人工核对小红书发布页 DOM 是否变化","为弹窗等待设置可配置的超时并在失败时打印页面截图","确保账号处于登录态且有商品/带货权限"],"tags":["timeout","ui-automation","selector","xiaohongshu"],"backgroundTag":"element-wait-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"}