{"record":{"id":"9955e916be7a2bd6","repo":"chenhg5/cc-connect","slug":"get-bot-qrcode-w","errorCode":null,"errorMessage":"get_bot_qrcode: %w","messagePattern":"get_bot_qrcode: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cc-connect/weixin.go","lineNumber":436,"sourceCode":"\tif len(s) <= max {\n\t\treturn s\n\t}\n\treturn s[:max] + \"…\"\n}\n\nfunc weixinFetchBotQRCode(ctx context.Context, apiBase, botType, routeTag string, debug bool) (*weixinBotQRResponse, error) {\n\tbase := strings.TrimRight(apiBase, \"/\") + \"/\"\n\tu, err := url.Parse(base)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tu = u.JoinPath(\"ilink\", \"bot\", \"get_bot_qrcode\")\n\tq := u.Query()\n\tq.Set(\"bot_type\", botType)\n\tu.RawQuery = q.Encode()\n\traw, err := weixinHTTPGet(ctx, u.String(), routeTag, debug)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"get_bot_qrcode: %w\", err)\n\t}\n\tvar out weixinBotQRResponse\n\tif err := json.Unmarshal(raw, &out); err != nil {\n\t\treturn nil, fmt.Errorf(\"get_bot_qrcode json: %w\", err)\n\t}\n\treturn &out, nil\n}\n\nfunc weixinPollQRStatus(ctx context.Context, apiBase, qrKey, routeTag string, debug bool) (*weixinQRStatusResponse, error) {\n\tbase := strings.TrimRight(apiBase, \"/\") + \"/\"\n\tu, err := url.Parse(base)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tu = u.JoinPath(\"ilink\", \"bot\", \"get_qrcode_status\")\n\tq := u.Query()\n\tq.Set(\"qrcode\", qrKey)\n\tu.RawQuery = q.Encode()","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/cmd/cc-connect/weixin.go#L418-L454","documentation":"weixinFetchBotQRCode calls weixinHTTPGet against the ilink `get_bot_qrcode` endpoint; if that HTTP request fails (including the non-200 http %d error from [481]), it wraps the failure with this `get_bot_qrcode:` prefix. The wrapped error chain retains the status code and body snippet from the inner error.","triggerScenarios":"runWeixinQRLoginFlow requests a bot QR code and the GET to `ilink/bot/get_bot_qrcode` returns a network error or a non-200 HTTP status.","commonSituations":"Incorrect api_base in the weixin config; bot_type query value rejected by the server; offline machine or blocked network; ilink service incident.","solutions":["Inspect the wrapped cause (%w chain) for the HTTP status and body snippet","Confirm api_base and bot_type are valid for your WeChat bot setup","Test the endpoint manually with curl using the same URL and query parameters","Retry if the cause indicates a transient 5xx/429 response"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"qr, err := weixinFetchBotQRCode(ctx, apiBase, botType, routeTag, debug)\nif err != nil {\n    var transient bool\n    var he *weixinHTTPError\n    if errors.As(err, &he) { transient = he.Status == 429 || he.Status >= 500 }\n    if transient { /* retry with backoff */ } else { return err }\n}","preventionTips":["Confirm api_base and bot_type values before setup","Retry only transient (429/5xx) failures","Test the endpoint manually with curl first","Monitor ilink service status during incidents"],"tags":["http","network","weixin","qr-login"],"backgroundTag":"api-request-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}