{"record":{"id":"24c94d8ae6a7eefd","repo":"fish2018/pansou","slug":"s-api-d","errorCode":null,"errorMessage":"[%s] 搜索 API 返回状态码: %d","messagePattern":"\\[(.+?)\\] 搜索 API 返回状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/feikuai/feikuai.go","lineNumber":133,"sourceCode":"\t}\n\n\t// 设置请求头\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://feikuai.tv/\")\n\n\t// 发送请求（带重试）\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn p.searchWeb(client, keyword, fmt.Errorf(\"[%s] 搜索 API 请求失败: %w\", p.Name(), err))\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查状态码\n\tif resp.StatusCode != 200 {\n\t\treturn p.searchWeb(client, keyword, fmt.Errorf(\"[%s] 搜索 API 返回状态码: %d\", p.Name(), resp.StatusCode))\n\t}\n\n\t// 读取并解析JSON响应\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn p.searchWeb(client, keyword, fmt.Errorf(\"[%s] 读取 API 响应失败: %w\", p.Name(), err))\n\t}\n\n\tvar apiResp FeikuaiAPIResponse\n\tif err := json.Unmarshal(body, &apiResp); err != nil {\n\t\treturn p.searchWeb(client, keyword, fmt.Errorf(\"[%s] API JSON 解析失败: %w\", p.Name(), err))\n\t}\n\n\t// 检查API响应状态\n\tif apiResp.Code != 0 {\n\t\treturn p.searchWeb(client, keyword, fmt.Errorf(\"[%s] API 返回错误: %s (code: %d)\", p.Name(), apiResp.Msg, apiResp.Code))\n\t}\n","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/feikuai/feikuai.go#L115-L151","documentation":"After the API request succeeds at transport level, searchImpl requires HTTP 200; any other status triggers the searchWeb HTML fallback with this error carrying the status code. It indicates the API responded but rejected or redirected the request.","triggerScenarios":"resp.StatusCode != 200 — e.g. 403 from anti-bot protection, 404 after a domain migration, 429 rate limit, 5xx upstream outage.","commonSituations":"Cloudflare/WAF blocking non-browser requests, stale Referer/User-Agent headers after site update, hitting rate limits under heavy scanning.","solutions":["Log the status code and response body snippet to identify the cause (403 vs 429 vs 5xx)","Update User-Agent/Referer/Accept headers to mimic a current browser","Slow down request rate or add backoff if 429","Update the API base URL if the site migrated domains"],"exampleFix":"// before\nif resp.StatusCode != 200 {\n    return p.searchWeb(client, keyword, fmt.Errorf(\"[%s] 搜索 API 返回状态码: %d\", p.Name(), resp.StatusCode))\n}\n// after\nif resp.StatusCode != http.StatusOK {\n    if resp.StatusCode == http.StatusTooManyRequests {\n        time.Sleep(2 * time.Second)\n    }\n    return p.searchWeb(client, keyword, fmt.Errorf(\"[%s] 搜索 API 返回状态码: %d\", p.Name(), resp.StatusCode))\n}","handlingStrategy":"retry","validationCode":"// can't pre-validate server status; add preflight rate limiting\nlimiter.Wait(ctx) // ensure request rate stays under upstream limits","typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(keyword)\nif err != nil {\n    var statusErr *statusError // if plugin exposes typed status errors\n    if errors.As(err, &statusErr) && statusErr.Code == 429 {\n        time.Sleep(time.Until(time.Now().Add(30 * time.Second)))\n        results, err = plugin.Search(keyword)\n    }\n}","preventionTips":["Send current, realistic browser headers (User-Agent, Referer)","Respect robots.txt and add jitter between requests","Handle 429 with exponential backoff before falling back","Alert on persistent 403/404 — it usually means the site changed domains or added WAF"],"tags":["http","status-code","anti-bot"],"backgroundTag":"http-non-200-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"}