{"record":{"id":"2cb069d63e8f7a65","repo":"fish2018/pansou","slug":"s-d-2cb069","errorCode":null,"errorMessage":"[%s] 搜索接口返回状态码: %d","messagePattern":"\\[(.+?)\\] 搜索接口返回状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/miosou/miosou.go","lineNumber":118,"sourceCode":"\t\tsetHeaders(req, \"text/event-stream\")\n\t\tresp, err := p.client.Do(req)\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t\t}\n\t\tif isAnubisGateResponse(resp) {\n\t\t\tresp.Body.Close()\n\t\t\tcancel()\n\t\t\tp.invalidateGate()\n\t\t\tif err := p.ensureGate(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tresp.Body.Close()\n\t\t\tcancel()\n\t\t\treturn nil, fmt.Errorf(\"[%s] 搜索接口返回状态码: %d\", p.Name(), resp.StatusCode)\n\t\t}\n\t\tgroups, err := parseSearchStream(resp.Body)\n\t\tresp.Body.Close()\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t\treturn nil, fmt.Errorf(\"[%s] 解析搜索流失败: %w\", p.Name(), err)\n\t\t}\n\t\tresults := p.convertGroups(ctx, groups, keyword)\n\t\tcancel()\n\t\treturn results, nil\n\t}\n\treturn nil, fmt.Errorf(\"[%s] 人机验证会话失效\", p.Name())\n}\n\nfunc (p *MiosouPlugin) ensureGate() error {\n\tp.gateMu.Lock()\n\tdefer p.gateMu.Unlock()\n\tif p.gateReady {","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/miosou/miosou.go#L100-L136","documentation":"This error is returned by MiosouPlugin.searchImpl when the search API responds with a status code other than 200 (and the response is not detected as an Anubis gate page). The plugin closes the body, cancels the context, and fails fast with the numeric code embedded rather than parsing a non-200 body.","triggerScenarios":"searchImpl's client.Do succeeds, isAnubisGateResponse returns false, but resp.StatusCode is e.g. 403 (blocked), 429 (rate limited), 500/502/503 (upstream error) on both allowed attempts' first pass — the loop does not retry non-200 non-gate responses.","commonSituations":"Server-side rate limiting after frequent searches; IP blocked by the site's firewall; temporary upstream outage (502/503); API endpoint removed or moved (404) after a site update.","solutions":["Read the status code from the message; 429/403 means slow down or change IP, 5xx means retry later","Check the API endpoint in a browser/curl to see if it still exists (404) or is protected (403)","Reduce search frequency / add jitter between searches to avoid rate limiting","Keep headers (setHeaders with Accept: text/event-stream) consistent with what the API expects"],"exampleFix":"// caller-side classification\nerr := search(...)\nif strings.Contains(err.Error(), \"状态码: 429\") {\n    time.Sleep(2 * time.Minute)\n} else if strings.Contains(err.Error(), \"状态码: 5\") {\n    // transient upstream error, retry with backoff\n}","handlingStrategy":"retry","validationCode":"// Go: probe the endpoint before real searches\nresp, err := http.Get(apiBaseURL + \"/search?keyword=test\")\nif err == nil {\n    io.Copy(io.Discard, io.LimitReader(resp.Body, 1<<10))\n    resp.Body.Close()\n    if resp.StatusCode != http.StatusOK {\n        // endpoint degraded/blocked; skip batch\n    }\n}","typeGuard":"func isStatusErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"搜索接口返回状态码\")\n}","tryCatchPattern":"if err != nil {\n    if isStatusErr(err) {\n        if strings.Contains(err.Error(), \"429\") {\n            time.Sleep(2 * time.Minute) // rate limited: back off\n        }\n        return nil, err\n    }\n}","preventionTips":["Throttle search frequency below the site's rate limit","Reuse one client so gate cookies persist","Keep Accept: text/event-stream headers intact","Alert on 404 to catch endpoint removals after site updates"],"tags":["http","status-code","rate-limit","upstream"],"backgroundTag":"http-non-200-response","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}