{"record":{"id":"14d5b2c1abe8df97","repo":"fish2018/pansou","slug":"http-d-14d5b2","errorCode":null,"errorMessage":"HTTP状态码: %d","messagePattern":"HTTP状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/wanou/wanou.go","lineNumber":446,"sourceCode":"\tif len(matches) > 1 {\n\t\treturn matches[1]\n\t}\n\treturn \"\"\n}\n\n// doRequestWithRetry 带重试的HTTP请求（优化JSON API的重试策略）\nfunc (p *WanouAsyncPlugin) doRequestWithRetry(req *http.Request, client *http.Client) (*http.Response, error) {\n\tmaxRetries := 2  // 对于JSON API减少重试次数\n\tvar lastErr error\n\t\n\tfor i := 0; i < maxRetries; i++ {\n\t\tresp, err := client.Do(req)\n\t\tif err == nil {\n\t\t\tif resp.StatusCode == http.StatusOK {\n\t\t\t\treturn resp, nil\n\t\t\t}\n\t\t\tresp.Body.Close()\n\t\t\tlastErr = fmt.Errorf(\"HTTP状态码: %d\", resp.StatusCode)\n\t\t} else {\n\t\t\tlastErr = err\n\t\t}\n\t\t\n\t\t// JSON API快速重试：只等待很短时间\n\t\tif i < maxRetries-1 {\n\t\t\ttime.Sleep(100 * time.Millisecond) // 从秒级改为100毫秒\n\t\t}\n\t}\n\t\n\treturn nil, fmt.Errorf(\"[%s] 请求失败，重试%d次后仍失败: %w\", p.Name(), maxRetries, lastErr)\n}\n\n// GetPerformanceStats 获取性能统计信息\nfunc (p *WanouAsyncPlugin) GetPerformanceStats() map[string]interface{} {\n\ttotalRequests := atomic.LoadInt64(&searchRequests)\n\ttotalTime := atomic.LoadInt64(&totalSearchTime)\n\t","sourceCodeStart":428,"sourceCodeEnd":464,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/wanou/wanou.go#L428-L464","documentation":"doRequestWithRetry retries the HTTP request; on each attempt with successful transport but non-200 status, it closes the body and records 'HTTP状态码: %d' as lastErr, then retries. If all attempts return non-200, this is the error surfaced to the caller. It means the server responded but rejected the request.","triggerScenarios":"searchImpl calling doRequestWithRetry when the wanou endpoint persistently returns 403 (anti-bot), 429 (rate limited), 5xx, or 404 across all retries.","commonSituations":"Datacenter IP blocked by the mirror; too-frequent requests triggering 429; the site under maintenance (503); old domain now serving 404.","solutions":["Log/inspect the status code: 403→anti-bot (add headers/cookies), 429→slow down, 5xx→retry later","Increase sleep between retries for 429 responses","Rotate mirror domains on repeated non-200","Add browser-like headers and cookies to defeat simple anti-bot checks"],"exampleFix":"// before\nlastErr = fmt.Errorf(\"HTTP状态码: %d\", resp.StatusCode)\n// after\nlastErr = fmt.Errorf(\"HTTP状态码: %d\", resp.StatusCode)\nif resp.StatusCode == http.StatusTooManyRequests {\n    time.Sleep(2 * time.Second) // honor rate limit before next retry\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, err := plugin.Search(ctx, q)\nif strings.Contains(err.Error(), \"HTTP状态码: 429\") {\n    time.Sleep(time.Duration(retryAfter) * time.Second)\n    // retry with lower rate\n} else if strings.Contains(err.Error(), \"HTTP状态码: 40\") {\n    // switch mirror / fix credentials — retrying won't help\n}","preventionTips":["Adapt behavior per status class (4xx vs 5xx vs 429)","Use browser-like headers to reduce 403s","Throttle requests below the site's rate limit","Rotate mirrors on repeated non-200"],"tags":["http","status-code","retry","anti-bot"],"backgroundTag":"http-error-status","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"}