{"record":{"id":"b36072dc5fc8cd15","repo":"fish2018/pansou","slug":"s-d-b36072","errorCode":null,"errorMessage":"[%s] 请求返回状态码: %d","messagePattern":"\\[(.+?)\\] 请求返回状态码: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/nsgame/nsgame.go","lineNumber":167,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 创建请求失败: %w\", p.Name(), err)\n\t}\n\n\t// 4. 设置请求头\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 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\tp.setRequestHeaders(req, \"https://nsthwj.cn/\")\n\n\t// 5. 发送请求（带重试机制）\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\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] 请求返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\n\t// 6. 读取响应体\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 读取响应失败: %w\", p.Name(), err)\n\t}\n\n\t// 7. 解析JSON响应\n\tvar apiResp NSGameResponse\n\tif err := json.Unmarshal(body, &apiResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] JSON解析失败: %w\", p.Name(), err)\n\t}\n\n\t// 8. 检查响应状态\n\tif !apiResp.Success || (apiResp.Code != \"\" && apiResp.Code != \"200\") {\n\t\treturn nil, fmt.Errorf(\"[%s] API返回错误: success=%v, code=%s\", p.Name(), apiResp.Success, apiResp.Code)\n\t}","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/nsgame/nsgame.go#L149-L185","documentation":"The NSGame search API returned an HTTP status code other than 200; the plugin treats any non-200 as a hard failure and surfaces the raw code. This happens after the request itself succeeded (no transport error), meaning the server actively responded with an error or redirect/anti-bot page status.","triggerScenarios":"Server responds 403/429/503 from anti-bot or rate limiting, 5xx from upstream outage, 404 when the apiURL path changed, or 302/301 if the client follows redirects to an HTML page with an error status.","commonSituations":"The site deployed Cloudflare/WAF challenge returning 403, scraping too aggressively triggering 429, site maintenance returning 502/503, or the plugin's hardcoded apiURL changed after a site update.","solutions":["Log resp.Status and a body snippet on non-200 to identify the actual blocker (WAF page vs 5xx)","Reduce request frequency / add jittered backoff if 429","Check whether nsthwj.cn changed its API path and update apiURL","Send the session headers/cookies produced by ensureSession (setRequestHeaders with Referer https://nsthwj.cn/) exactly as a browser would to pass WAF checks","Retry later if it's a 5xx outage"],"exampleFix":"// before\nif resp.StatusCode != 200 {\n    return nil, fmt.Errorf(\"[%s] 请求返回状态码: %d\", p.Name(), resp.StatusCode)\n}\n// after\nif resp.StatusCode != 200 {\n    snippet, _ := io.ReadAll(io.LimitReader(resp.Body, 256))\n    return nil, fmt.Errorf(\"[%s] 请求返回状态码: %d, body: %s\", p.Name(), resp.StatusCode, snippet)\n}","handlingStrategy":"retry","validationCode":"// preemptive check of upstream health\nresp, err := http.Get(\"https://nsthwj.cn/\")\nif err == nil && resp.StatusCode == http.StatusForbidden {\n    log.Warn(\"upstream WAF is blocking this IP\")\n}\nif resp != nil { resp.Body.Close() }","typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(keyword, ext)\nvar statusErr *plugin.StatusError\nif errors.As(err, &statusErr) && statusErr.Code == 429 {\n    time.Sleep(backoff)\n    // retry once\n}","preventionTips":["Throttle request rate to avoid 429 rate limiting","Log response status and a body snippet to detect WAF/Cloudflare pages early","Keep browser-like headers (User-Agent, Referer) current","Alert on sustained non-200 rates so site changes are noticed"],"tags":["http","status-code","anti-bot","go"],"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"}