{"record":{"id":"1ed3b7c284f3a9a0","repo":"fish2018/pansou","slug":"s-d-1ed3b7","errorCode":null,"errorMessage":"[%s] 首页返回状态码: %d","messagePattern":"\\[(.+?)\\] 首页返回状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/jsnoteclub/jsnoteclub.go","lineNumber":241,"sourceCode":"\nfunc (p *JsNoteClubPlugin) fetchDataKey(client *http.Client) (string, error) {\n\tctx, cancel := context.WithTimeout(context.Background(), requestTimeout)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, \"https://jsnoteclub.com/\", nil)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"[%s] 创建首页请求失败: %w\", p.Name(), err)\n\t}\n\tsetHTMLHeaders(req, \"https://jsnoteclub.com/\")\n\n\tresp, err := p.doRequestWithRetry(req, client, maxRequestRetries)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"[%s] 访问首页失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"[%s] 首页返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\n\tdoc, err := goquery.NewDocumentFromReader(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"[%s] 解析首页失败: %w\", p.Name(), err)\n\t}\n\n\tvar htmlBuilder strings.Builder\n\tdoc.Find(\"script\").Each(func(_ int, s *goquery.Selection) {\n\t\tif html, err := goquery.OuterHtml(s); err == nil {\n\t\t\thtmlBuilder.WriteString(html)\n\t\t}\n\t})\n\n\tmatch := dataKeyRegex.FindStringSubmatch(htmlBuilder.String())\n\tif len(match) < 2 {\n\t\treturn \"\", fmt.Errorf(\"[%s] 未能在首页找到 data-key\", p.Name())\n\t}","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/jsnoteclub/jsnoteclub.go#L223-L259","documentation":"Returned when the homepage request succeeds at the transport level but the server responds with a status code other than 200 OK. The plugin treats any non-200 homepage response as a hard failure and includes the numeric status in the message.","triggerScenarios":"GET https://jsnoteclub.com/ returns e.g. 403 (bot blocking/WAF), 429 (rate limit), 5xx (server error), or a 3xx that was not followed to a 200.","commonSituations":"Cloudflare or nginx blocking the plugin's User-Agent; server under maintenance returning 502/503; hitting the site too frequently and being rate limited; the site moved/redirected in a way the client's CheckRedirect policy rejects.","solutions":["Log/read the status code in the message: 403/429 means blocking — change or rotate User-Agent headers in setHTMLHeaders","Back off and retry later for 5xx codes (server-side problem)","Reduce request frequency / add caching to avoid rate limits","Check https://jsnoteclub.com/ manually in a browser to see if the site changed or moved","Inspect response body for Cloudflare challenge pages and adjust headers accordingly"],"exampleFix":"// before\nif resp.StatusCode != http.StatusOK {\n    return \"\", fmt.Errorf(\"[%s] 首页返回状态码: %d\", p.Name(), resp.StatusCode)\n}\n// after\nif resp.StatusCode != http.StatusOK {\n    return \"\", fmt.Errorf(\"[%s] 首页返回状态码: %d\", p.Name(), resp.StatusCode) // 403/429 => adjust User-Agent; 5xx => retry with backoff\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"key, err := plugin.fetchDataKey(client)\nif err != nil {\n    var statusErr interface{ Error() string }\n    if strings.Contains(err.Error(), \"首页返回状态码\") {\n        // non-200 from upstream: handle 403/429 by rotating headers, 5xx by waiting\n        return handleUpstreamStatus(err)\n    }\n    _ = statusErr\n    return err\n}","preventionTips":["Send realistic browser User-Agent/Accept headers via setHTMLHeaders to avoid bot blocks","Rate-limit your scraping frequency and cache homepage results","Monitor the site's status codes; 403/429 patterns indicate you should back off","Alert on 5xx responses rather than immediately retrying"],"tags":["http","status-code","scraping","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"}