{"record":{"id":"47b50df01edccf29","repo":"chenhg5/cc-connect","slug":"refresh-qr-w","errorCode":null,"errorMessage":"refresh QR: %w","messagePattern":"refresh QR: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cc-connect/weixin.go","lineNumber":342,"sourceCode":"\t\t\t}\n\t\t\ttime.Sleep(time.Second)\n\t\t\tcontinue\n\t\tcase \"scaned\":\n\t\t\tif !scannedPrinted {\n\t\t\t\tfmt.Println(\"\\n已扫码，请在手机上确认登录…\")\n\t\t\t\tscannedPrinted = true\n\t\t\t}\n\t\t\ttime.Sleep(time.Second)\n\t\t\tcontinue\n\t\tcase \"expired\":\n\t\t\trefreshCount++\n\t\t\tif refreshCount > weixinMaxQRRefresh {\n\t\t\t\treturn nil, fmt.Errorf(\"二维码多次过期，请重试 setup\")\n\t\t\t}\n\t\t\tfmt.Printf(\"\\n二维码已过期，正在刷新 (%d/%d)…\\n\", refreshCount, weixinMaxQRRefresh)\n\t\t\tnewQR, err := weixinFetchBotQRCode(ctx, opts.APIBaseURL, botType, opts.RouteTag, opts.Debug)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"refresh QR: %w\", err)\n\t\t\t}\n\t\t\tqrKey = newQR.QRCode\n\t\t\tqrFetchedAt = time.Now()\n\t\t\tscannedPrinted = false\n\t\t\tnewURL := strings.TrimSpace(newQR.QRCodeImgContent)\n\t\t\tif newURL != \"\" {\n\t\t\t\tfmt.Println(\"请扫描新二维码：\")\n\t\t\t\tfmt.Printf(\"URL: %s\\n\\n\", newURL)\n\t\t\t\ttryPrintTerminalQRCode(newURL)\n\t\t\t}\n\t\t\t// 过期刷新时同步更新 QR 图片文件\n\t\t\tif opts.QRImage != \"\" {\n\t\t\t\tif err := saveQRCodeImage(newURL, opts.QRImage); err != nil {\n\t\t\t\t\tfmt.Fprintf(os.Stderr, \"Warning: failed to update QR image: %v\\n\", err)\n\t\t\t\t} else {\n\t\t\t\t\tfmt.Printf(\"QR code updated at: %s\\n\\n\", opts.QRImage)\n\t\t\t\t}\n\t\t\t}","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/cmd/cc-connect/weixin.go#L324-L360","documentation":"When the polled login QR status is \"expired\", runWeixinQRLoginFlow fetches a replacement QR via weixinFetchBotQRCode. If that refresh HTTP call fails, the flow aborts with \"refresh QR: %w\" wrapping the underlying error. The original QR is already dead at this point, so the login session cannot continue.","triggerScenarios":"Mid-setup, the QR expires; the automatic refresh call weixinFetchBotQRCode(ctx, opts.APIBaseURL, botType, opts.RouteTag, opts.Debug) returns a network/API error (DNS failure, timeout, 5xx, auth rejection).","commonSituations":"Flaky network or VPN drop during setup; ilink API outage or rate limiting that begins mid-session; misconfigured APIBaseURL that intermittently fails; corporate proxy killing long-lived sessions.","solutions":["Read the wrapped root cause (%w) — fix the underlying network/API issue it names.","Retry `cc-connect weixin setup`; transient network errors usually clear.","Verify APIBaseURL and RouteTag configuration are correct and reachable (curl the endpoint).","Check for ilink service incidents or rate limits; wait and retry.","Alternatively use `cc-connect weixin bind --token ...` to skip the QR flow."],"exampleFix":"// before: single refresh attempt, hard fail\nnewQR, err := weixinFetchBotQRCode(ctx, ...)\nif err != nil { return nil, fmt.Errorf(\"refresh QR: %w\", err) }\n\n// after: bounded retry with backoff\nvar newQR *qrPayload\nfor i := 0; i < 3; i++ {\n    newQR, err = weixinFetchBotQRCode(ctx, ...)\n    if err == nil { break }\n    time.Sleep(time.Duration(1<<i) * time.Second)\n}\nif err != nil { return nil, fmt.Errorf(\"refresh QR: %w\", err) }","handlingStrategy":"retry","validationCode":"// Pre-flight the endpoint before starting the QR flow:\nresp, err := http.Head(apiBaseURL + healthPath)\nif err != nil || resp.StatusCode >= 500 {\n    return fmt.Errorf(\"API endpoint %s unhealthy, aborting QR setup\", apiBaseURL)\n}","typeGuard":null,"tryCatchPattern":"res, err := runWeixinQRLoginFlow(ctx, opts)\nif err != nil {\n    var wrapped error\n    if strings.Contains(err.Error(), \"refresh QR:\") {\n        wrapped = err // network blip mid-flow; safe to retry the whole setup\n    }\n    return retrySetup(wrapped)\n}","preventionTips":["Ensure stable connectivity (avoid flaky VPN/proxy) before running setup","Validate APIBaseURL with a quick health check first","Implement bounded exponential backoff for the refresh fetch","Fall back to token-based bind when the network is unreliable"],"tags":["weixin","qrcode","network"],"backgroundTag":"http-request-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}