{"record":{"id":"069cf75405b72873","repo":"fish2018/pansou","slug":"s-s-d-w-069cf7","errorCode":null,"errorMessage":"[%s] %s网盘第%d页请求失败: %w","messagePattern":"\\[(.+?)\\] (.+?)网盘第(.+?)页请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/sdso/sdso.go","lineNumber":251,"sourceCode":"\tdefer cancel()\n\n\t// 3. 创建请求对象\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] %s网盘第%d页创建请求失败: %w\", p.Name(), fromType, pageNo, err)\n\t}\n\n\t// 4. 设置请求头\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"application/json, text/plain, */*\")\n\treq.Header.Set(\"Accept-Language\", \"zh-CN,zh;q=0.9,en;q=0.8\")\n\treq.Header.Set(\"Connection\", \"keep-alive\")\n\treq.Header.Set(\"Referer\", \"https://sdso.top/\")\n\n\t// 5. 发送HTTP请求（带重试机制）\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] %s网盘第%d页请求失败: %w\", p.Name(), fromType, pageNo, err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 6. 检查状态码\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] %s网盘第%d页返回状态码: %d\", p.Name(), fromType, pageNo, resp.StatusCode)\n\t}\n\n\t// 7. 解析响应\n\tvar apiResp APIResponse\n\tif err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] %s网盘第%d页JSON解析失败: %w\", p.Name(), fromType, pageNo, err)\n\t}\n\n\t// 8. 检查API响应状态\n\tif apiResp.Code != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] %s网盘第%d页API错误: %s\", p.Name(), fromType, pageNo, apiResp.Msg)\n\t}","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/sdso/sdso.go#L233-L269","documentation":"fetchSinglePageWithType wraps errors from doRequestWithRetry, which performs the actual HTTP GET to sdso.top with up to 3 attempts (exponential backoff). This error means the request failed on every attempt — network-level failure, timeout (30s context), TLS error, or every attempt returned a non-200 status.","triggerScenarios":"client.Do fails 3 consecutive times for a page request: DNS resolution failure, connection refused/reset, TLS handshake error, the 30-second context deadline expiring, or repeated non-200 responses (note: non-200 bodies are also treated as retryable failures inside doRequestWithRetry).","commonSituations":"sdso.top is down or blocking the client; no outbound internet on the deployment host; a slow connection exceeding the 30s timeout; GFW/network filtering of the domain; the server returning 403/429 on all retries due to rate limiting.","solutions":["Test reachability: curl -v https://sdso.top/api/sd/search?name=test&pageNo=1&from=baidu.","Check for 403/429 responses — slow down or rotate IP/User-Agent if the site is rate-limiting.","Increase the 30s context timeout or add more retries if the network is slow but healthy.","Verify DNS/proxy configuration on the host (HTTP_PROXY/HTTPS_PROXY env, /etc/resolv.conf).","Inspect the wrapped lastErr in the error message for the concrete transport cause."],"exampleFix":"// before\nclient := &http.Client{} // no proxy support\n// after\nclient := &http.Client{\n    Transport: &http.Transport{\n        Proxy: http.ProxyFromEnvironment,\n        TLSHandshakeTimeout: 10 * time.Second,\n    },\n}","handlingStrategy":"retry","validationCode":"conn, err := net.DialTimeout(\"tcp\", \"sdso.top:443\", 5*time.Second)\nif err != nil { /* skip source: unreachable */ }","typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(ctx, keyword)\nif err != nil && strings.Contains(err.Error(), \"重试\") {\n    // transport failed after retries; back off before next attempt\n    time.Sleep(5 * time.Second)\n}","preventionTips":["Configure HTTP proxy env vars on hosts behind firewalls","Keep the 30s request timeout but tolerate slow networks with retries","Cap pages-per-type to limit exposure to transient failures","Check the wrapped lastErr for the concrete transport cause"],"tags":["network","http","timeout","retry","go"],"backgroundTag":"http-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"}