{"record":{"id":"4749a7b47fab0a41","repo":"fish2018/pansou","slug":"s-buildid-w-4749a7","errorCode":null,"errorMessage":"[%s] 刷新 buildId 后获取首页失败: %w","messagePattern":"\\[(.+?)\\] 刷新 buildId 后获取首页失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/pansearch/pansearch.go","lineNumber":525,"sourceCode":"\tbaseURL, err := p.getBaseURL(client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 获取API基础URL失败: %w\", p.Name(), err)\n\t}\n\n\tfirstPageResults, total, err := p.fetchFirstPage(keyword, baseURL, client)\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"404\") || strings.Contains(err.Error(), \"Not Found\") {\n\t\t\tbuildIdMutex.Lock()\n\t\t\tbuildIdCache = \"\"\n\t\t\tbuildIdCacheTime = time.Time{}\n\t\t\tbuildIdMutex.Unlock()\n\t\t\tbaseURL, err = p.getBaseURL(client)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"[%s] 刷新 buildId 失败: %w\", p.Name(), err)\n\t\t\t}\n\t\t\tfirstPageResults, total, err = p.fetchFirstPage(keyword, baseURL, client)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"[%s] 刷新 buildId 后获取首页失败: %w\", p.Name(), err)\n\t\t\t}\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"[%s] 获取首页失败: %w\", p.Name(), err)\n\t\t}\n\t}\n\n\tallResults := append([]PanSearchItem(nil), firstPageResults...)\n\tpageCount := min((min(total, p.maxResults)+PageSize-1)/PageSize, MaxAPIPages)\n\tif pageCount > 1 {\n\t\ttype pageResult struct {\n\t\t\toffset int\n\t\t\titems  []PanSearchItem\n\t\t}\n\t\tresultCh := make(chan pageResult, pageCount-1)\n\t\tsem := make(chan struct{}, min(p.maxConcurrent, pageCount-1))\n\t\tvar wg sync.WaitGroup\n\n\t\tfor page := 1; page < pageCount; page++ {","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/pansearch/pansearch.go#L507-L543","documentation":"Recovery-path error in pansearch's doSearch (plugin/pansearch/pansearch.go:525): after a 404 triggered a buildId cache reset, re-fetching the site's base URL/buildId failed again, so the fallback recovery itself failed and the search aborts.","triggerScenarios":"buildId was refreshed but the retried fetchFirstPage still failed — network error, timeout, another 404, or another non-200 status from the search API.","commonSituations":"站点频繁重新部署导致 buildId 连续变化；getBaseURL 解析页面失败。","solutions":["Check the wrapped error to determine whether the retry failed with 404 again or a network/timeout error.","If 404 persists, the search API URL scheme may have changed — verify against the current upstream frontend requests.","Retry later with backoff; the issue may be transient upstream instability.","Capture the request URL used and compare it with the upstream site's live API calls."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"刷新 buildId 后获取首页失败\") {\n    // even the retry failed — treat as upstream outage\n    return err\n}","preventionTips":["Don't retry immediately in a loop; use backoff since the built-in retry already failed","Verify the search API URL format against the live site when this recurs","Monitor for persistent failures indicating an API endpoint change"],"tags":["http","retry","search-api","upstream"],"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"}