{"record":{"id":"0d4c49315c6e3f44","repo":"fish2018/pansou","slug":"w-0d4c49","errorCode":null,"errorMessage":"请求失败: %w","messagePattern":"请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/pansearch/pansearch.go","lineNumber":412,"sourceCode":"\t\t}\n\n\t\tresp, respErr = p.GetClient().Do(req)\n\t\tif respErr == nil && resp.StatusCode == 200 {\n\t\t\tbreak\n\t\t}\n\n\t\tif resp != nil {\n\t\t\tresp.Body.Close()\n\t\t}\n\t}\n\n\t// 如果所有重试都失败，但有旧的缓存，使用旧的缓存（优雅降级）\n\tif respErr != nil || resp == nil {\n\t\tif buildIdCache != \"\" {\n\t\t\t// fmt.Printf(\"请求失败，使用旧的buildId: %v\\n\", respErr)\n\t\t\treturn buildIdCache, nil\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"请求失败: %w\", respErr)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\t// 如果状态码不是200，但有旧的缓存，使用旧的缓存（优雅降级）\n\t\tif buildIdCache != \"\" {\n\t\t\tfmt.Printf(\"获取buildId时服务器返回非200状态码: %d，使用旧的buildId\\n\", resp.StatusCode)\n\t\t\treturn buildIdCache, nil\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"获取buildId时服务器返回非200状态码: %d\", resp.StatusCode)\n\t}\n\n\t// 使用更高效的方式读取响应体\n\tvar bodyBuilder strings.Builder\n\t_, err = io.Copy(&bodyBuilder, resp.Body)\n\tif err != nil {\n\t\t// 如果读取响应失败，但有旧的缓存，使用旧的缓存（优雅降级）\n\t\tif buildIdCache != \"\" {","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/pansearch/pansearch.go#L394-L430","documentation":"getBuildId performed the HTTP request but it failed (respErr != nil or resp == nil) — e.g. DNS failure, timeout, connection refused — and there is no cached buildId to fall back on. The underlying error is wrapped in this error.","triggerScenarios":"client.Do fails on all retries: site unreachable, DNS resolution failure, request timeout, TLS error, or context canceled, with buildIdCache empty.","commonSituations":"Target site down or blocked (region/firewall); no internet/DNS issues in the deployment environment; timeout too aggressive for a slow site; first run without any cached buildId.","solutions":["Check network connectivity and whether the target site is reachable (curl the base URL)","Increase the HTTP client timeout and let the existing retry loop run","Persist buildIdCache to disk so restarts keep a fallback value","Configure a proxy if the site is blocked from your network"],"exampleFix":"// before\nbuildId, err := getBuildId(ctx)\nif err != nil { return \"\", err }\n// after\nbuildId, err := getBuildId(ctx)\nif err != nil {\n    if cached := loadBuildIdFromDisk(); cached != \"\" {\n        return cached, nil\n    }\n    return \"\", err\n}","handlingStrategy":"retry","validationCode":"resp, err := http.Head(siteBaseURL)\nif err != nil || resp.StatusCode >= 500 {\n    return errors.New(\"site unreachable before buildId fetch\")\n}","typeGuard":null,"tryCatchPattern":"buildId, err := getBuildId(ctx)\nif err != nil {\n    if cached := cachedBuildId(); cached != \"\" {\n        buildId = cached\n    } else {\n        return fmt.Errorf(\"buildId fetch failed and no cache: %w\", err)\n    }\n}","preventionTips":["Persist buildIdCache to disk across restarts","Use generous timeouts and let the retry loop absorb transient outages","Health-check the upstream site before scheduled scraping jobs"],"tags":["http","network","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"}