fish2018/pansou · error
[ ] 搜索会话返回状态码
Error message
[%s] 搜索会话返回状态码: %d
What it means
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.
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.
Defensive patterns
Strategy: retry
Try / catch
if err := p.ensureSearchSession(client); err != nil {
if strings.Contains(err.Error(), "搜索会话返回状态码: 429") {
select {
case <-time.After(rateLimitBackoff):
}
err = p.ensureSearchSession(client)
}
if err != nil { log.Printf("searching without session: %v", err) }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Anti-bot protection serving 403 challenge pages; upstream redesigned its API removing the session route; aggressive polling causing 429; temporary server outage.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/9e4f877c67406776.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/jupansou/jupansou.go:187
func (p *JuPansouPlugin) ensureSearchSession(client *http.Client) error {
ctx, cancel := context.WithTimeout(context.Background(), jupansouTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, jupansouBaseURL+"/api/search/session", nil)
if err != nil {
return fmt.Errorf("[%s] 创建搜索会话请求失败: %w", p.Name(), err)
}
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0 Safari/537.36")
req.Header.Set("Accept", "application/json")
req.Header.Set("Referer", jupansouBaseURL+"/")
req.Header.Set("X-Requested-With", "XMLHttpRequest")
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("[%s] 搜索会话请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("[%s] 搜索会话返回状态码: %d", p.Name(), resp.StatusCode)
}
return nil
}
func (p *JuPansouPlugin) exchangeItems(client *http.Client, items []juPansouStreamItem) []model.SearchResult {
results := make([]model.SearchResult, 0, len(items))
var wg sync.WaitGroup
var mu sync.Mutex
sem := make(chan struct{}, 8)
seen := make(map[string]struct{})
for _, item := range items {
item := item
if item.URL == "" {
continue
}
wg.Add(1)
sem <- struct{}{}
go func() {View on GitHub (pinned to beaa561337)