{"record":{"id":"c08df5662bdd8f83","repo":"fish2018/pansou","slug":"s-d-w-c08df5","errorCode":null,"errorMessage":"[%s] 请求失败，重试%d次后仍失败: %w","messagePattern":"\\[(.+?)\\] 请求失败，重试(.+?)次后仍失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/erxiao/erxiao.go","lineNumber":554,"sourceCode":"\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\tif req.Context().Err() != nil {\n\t\t\treturn nil, req.Context().Err()\n\t\t}\n\n\t\t// 快速重试：只等待很短时间\n\t\tif i < maxRetries-1 {\n\t\t\ttime.Sleep(100 * time.Millisecond)\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"[%s] 请求失败，重试%d次后仍失败: %w\", p.Name(), maxRetries, lastErr)\n}\n\n// GetPerformanceStats 获取性能统计信息\nfunc (p *ErxiaoAsyncPlugin) GetPerformanceStats() map[string]interface{} {\n\ttotalRequests := atomic.LoadInt64(&searchRequests)\n\ttotalTime := atomic.LoadInt64(&totalSearchTime)\n\tdetailRequests := atomic.LoadInt64(&detailPageRequests)\n\tdetailTime := atomic.LoadInt64(&totalDetailTime)\n\thits := atomic.LoadInt64(&cacheHits)\n\tmisses := atomic.LoadInt64(&cacheMisses)\n\n\tvar avgTime float64\n\tif totalRequests > 0 {\n\t\tavgTime = float64(totalTime) / float64(totalRequests) / 1e6 // 转换为毫秒\n\t}\n\n\tvar avgDetailTime float64\n\tif detailRequests > 0 {","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/erxiao/erxiao.go#L536-L572","documentation":"doRequestWithRetry in the Erxiao plugin retries an outgoing HTTP search request up to maxRetries times with short 100ms backoff and, if every attempt fails, wraps the last underlying error in this message. It signals that the upstream site could not be reached or did not answer successfully across all quick retries.","triggerScenarios":"All attempts inside doRequestWithRetry return non-nil errors (network failure, timeout, connection reset) and searchAtBase or fetchDetailLinksAndImages surfaces the wrapped lastErr.","commonSituations":"Upstream site blocked or geo-restricted, DNS failures, server under load or rate-limiting, local network outage, or 100ms backoff too short for a slow upstream.","solutions":["Inspect the wrapped %w cause to identify the concrete network error","Verify network/DNS connectivity to the erxiao upstream host","Increase maxRetries or the 100ms sleep backoff for slow upstreams","Add proxy support if the host is blocked from this environment"],"exampleFix":"// before\nreturn nil, fmt.Errorf(\"[%s] 请求失败，重试%d次后仍失败: %w\", p.Name(), maxRetries, lastErr)\n// after\nbackoff := 100 * time.Millisecond\nfor i := 0; i < maxRetries; i++ {\n    resp, err = client.Do(req)\n    if err == nil { break }\n    time.Sleep(backoff)\n    backoff *= 2\n}","handlingStrategy":"retry","validationCode":"// pre-check upstream reachability\nresp, err := http.Head(\"https://erxiao-upstream-host/\")\nif err != nil || resp.StatusCode >= 500 { /* skip plugin this round */ }","typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(keyword)\nif err != nil {\n    var retriable bool\n    if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, syscall.ECONNRESET) { retriable = true }\n    log.Printf(\"erxiao unavailable (retriable=%v): %v\", retriable, err)\n    results = nil // degrade gracefully to other plugins\n}","preventionTips":["Aggregate results from multiple plugins so one failing plugin degrades gracefully","Monitor the wrapped cause of retry-exhausted errors to detect upstream outages early","Use exponential backoff instead of fixed 100ms","Set sane per-request timeouts shorter than the overall context deadline"],"tags":["network","retry-exhausted","http"],"backgroundTag":"api-request-failed","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"}