{"record":{"id":"5d27ae738199efad","repo":"fish2018/pansou","slug":"s-w-5d27ae","errorCode":null,"errorMessage":"[%s] 搜索请求失败: %w","messagePattern":"\\[(.+?)\\] 搜索请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/pianku/pianku.go","lineNumber":141,"sourceCode":"\tsearchURL := fmt.Sprintf(\"%s%s?wd=%s\", BaseURL, SearchPath, url.QueryEscape(searchKeyword))\n\t\n\t// 创建带超时的上下文\n\tctx, cancel := context.WithTimeout(context.Background(), TimeoutSeconds*time.Second)\n\tdefer cancel()\n\t\n\t// 创建请求\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 创建请求失败: %w\", p.Name(), err)\n\t}\n\t\n\t// 设置请求头\n\tp.setRequestHeaders(req)\n\t\n\t// 发送HTTP请求（带重试机制）\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\t\n\t// 检查状态码\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] 请求返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\t\n\t// 解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] HTML解析失败: %w\", p.Name(), err)\n\t}\n\t\n\t// 提取搜索结果基本信息\n\tsearchResults := p.extractSearchResults(doc)\n\t\n\t// 为每个搜索结果获取详情页的下载链接","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/pianku/pianku.go#L123-L159","documentation":"The retry-wrapped search HTTP request (p.doRequestWithRetry) ultimately failed after exhausting its retries. The transport error is wrapped with the plugin name and returned, aborting the pianku search.","triggerScenarios":"All retry attempts of the GET to pianku's search page failed — persistent DNS failure, connection refused/reset, TLS errors, or request timeout against the configured HTTP client.","commonSituations":"Site unreachable from the server's network/region; pianku blocking datacenter IPs; DNS misconfiguration in the container; timeout too short for retries to help.","solutions":["Check connectivity to pianku from the host (curl the search URL)","Inspect the wrapped %w cause to distinguish DNS vs timeout vs connection reset","Increase retry count/timeout in doRequestWithRetry if failures are intermittent","Add a proxy or alternate endpoint if the site blocks the server's IP range"],"exampleFix":"// before\nresp, err := p.doRequestWithRetry(req, client)\nif err != nil {\n    return nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n}\n// after\nresp, err := p.doRequestWithRetry(req, client)\nif err != nil {\n    if ne, ok := err.(net.Error); ok && ne.Timeout() {\n        return nil, fmt.Errorf(\"[%s] 搜索请求超时(已重试): %w\", p.Name(), err)\n    }\n    return nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n}","handlingStrategy":"retry","validationCode":"conn, err := net.DialTimeout(\"tcp\", \"www.pianku.cc:443\", 5*time.Second)\nif err != nil { /* upstream unreachable */ } else { conn.Close() }","typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(keyword, ext)\nif err != nil {\n    var urlErr *url.Error\n    if errors.As(err, &urlErr) && urlErr.Timeout() {\n        // retry with longer timeout / backoff\n    } else {\n        // network-level failure: fail over to other plugins\n    }\n}","preventionTips":["Use exponential backoff on transport errors","Monitor DNS and egress connectivity in the deployment environment","Set sane client timeouts so retries have a chance to succeed"],"tags":["go","network","http","retry","plugin"],"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"}