{"record":{"id":"3a5f30411bdcd980","repo":"fish2018/pansou","slug":"buildid-200-d","errorCode":null,"errorMessage":"获取buildId时服务器返回非200状态码: %d","messagePattern":"获取buildId时服务器返回非200状态码: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/pansearch/pansearch.go","lineNumber":422,"sourceCode":"\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 != \"\" {\n\t\t\t// fmt.Printf(\"读取响应失败，使用旧的buildId: %v\\n\", err)\n\t\t\treturn buildIdCache, nil\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"读取响应失败: %w\", err)\n\t}\n\tbody := bodyBuilder.String()\n\n\t// 使用提取函数获取 buildId\n\tbuildId := extractBuildId(body)\n","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/pansearch/pansearch.go#L404-L440","documentation":"getBuildId fetches the upstream site's buildId (required to build search API URLs). If the HTTP response status is not 200 and no cached buildId exists, it fails hard with this error. If a cached buildId exists, it degrades gracefully and returns the stale cache instead.","triggerScenarios":"Calling getBuildId (via getBaseURL/doSearch) when the upstream server returns e.g. 403, 429, 5xx, or any non-200 status, while buildIdCache is empty (first call or cache was cleared).","commonSituations":"Upstream site is rate-limiting or blocking the client (missing cookies/Cloudflare challenge), upstream deployed a broken build, or the cache was invalidated so there is no fallback buildId.","solutions":["Check the actual status code printed and address the upstream cause (e.g. 429 → back off / slow down requests; 403 → update headers/cookies).","Wait and retry later; the module caches a valid buildId for a period, so after one success errors become rare.","Verify network/proxy connectivity to the upstream site from this host.","Retry the search, which re-invokes getBaseURL and re-fetches the buildId."],"exampleFix":"// before\nreturn \"\", fmt.Errorf(\"获取buildId时服务器返回非200状态码: %d\", resp.StatusCode)\n// after\nif resp.StatusCode == http.StatusTooManyRequests {\n    time.Sleep(2 * time.Second)\n    // retry once before failing\n}","handlingStrategy":"retry","validationCode":"// optionally probe the upstream before calling:\nresp, err := http.Get(baseSite)\nif err != nil || resp.StatusCode != 200 {\n    // defer or skip the search call\n}","typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(ctx, kw)\nif err != nil && strings.Contains(err.Error(), \"非200状态码\") {\n    // upstream returned non-200 without cached buildId: back off and retry later\n    time.Sleep(5 * time.Second)\n    results, err = plugin.Search(ctx, kw)\n}","preventionTips":["Keep requests at a modest rate to avoid upstream rate limiting","Monitor the log line about non-200 status — it indicates upstream trouble before hard failure","Run from a network location not blocked by the upstream's anti-bot layer"],"tags":["http","network","upstream","buildid"],"backgroundTag":"http-error-response","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"}