{"record":{"id":"9e4f877c67406776","repo":"fish2018/pansou","slug":"s-d-9e4f87","errorCode":null,"errorMessage":"[%s] 搜索会话返回状态码: %d","messagePattern":"\\[(.+?)\\] 搜索会话返回状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/jupansou/jupansou.go","lineNumber":187,"sourceCode":"\nfunc (p *JuPansouPlugin) ensureSearchSession(client *http.Client) error {\n\tctx, cancel := context.WithTimeout(context.Background(), jupansouTimeout)\n\tdefer cancel()\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, jupansouBaseURL+\"/api/search/session\", nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"[%s] 创建搜索会话请求失败: %w\", p.Name(), err)\n\t}\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"application/json\")\n\treq.Header.Set(\"Referer\", jupansouBaseURL+\"/\")\n\treq.Header.Set(\"X-Requested-With\", \"XMLHttpRequest\")\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"[%s] 搜索会话请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"[%s] 搜索会话返回状态码: %d\", p.Name(), resp.StatusCode)\n\t}\n\treturn nil\n}\n\nfunc (p *JuPansouPlugin) exchangeItems(client *http.Client, items []juPansouStreamItem) []model.SearchResult {\n\tresults := make([]model.SearchResult, 0, len(items))\n\tvar wg sync.WaitGroup\n\tvar mu sync.Mutex\n\tsem := make(chan struct{}, 8)\n\tseen := make(map[string]struct{})\n\tfor _, item := range items {\n\t\titem := item\n\t\tif item.URL == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\twg.Add(1)\n\t\tsem <- struct{}{}\n\t\tgo func() {","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/jupansou/jupansou.go#L169-L205","documentation":"ensureSearchSession returns this when the session endpoint replies with a non-200 status code. The session could not be established, so cookies needed by the search flow are missing. The body is discarded and only the numeric status is reported.","triggerScenarios":"The GET to /api/search/session completes but resp.StatusCode != http.StatusOK — e.g. 403 WAF challenge, 404 endpoint removed, 429 rate limit, 5xx outage.","commonSituations":"Anti-bot protection serving 403 challenge pages; upstream redesigned its API removing the session route; aggressive polling causing 429; temporary server outage.","solutions":["Check the code: 403 → anti-bot, adjust headers or use a real browser profile/cookies; 404 → endpoint moved, update plugin.","Slow down polling frequency if hitting 429.","curl the endpoint with identical headers to inspect the raw response.","Retry later on transient 5xx.","Consider making session failure non-fatal if searches still work without it."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := p.ensureSearchSession(client); err != nil {\n    if strings.Contains(err.Error(), \"搜索会话返回状态码: 429\") {\n        select {\n        case <-time.After(rateLimitBackoff):\n        }\n        err = p.ensureSearchSession(client)\n    }\n    if err != nil { log.Printf(\"searching without session: %v\", err) }\n}","preventionTips":["Space out session establishments; reuse sessions/cookies across searches.","Detect 403 challenge responses and rotate headers/proxy accordingly.","Track upstream API changes; pin and test the session endpoint contract."],"tags":["http","status-code","session","upstream"],"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"}