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

  1. Check the code: 403 → anti-bot, adjust headers or use a real browser profile/cookies; 404 → endpoint moved, update plugin.
  2. Slow down polling frequency if hitting 429.
  3. curl the endpoint with identical headers to inspect the raw response.
  4. Retry later on transient 5xx.
  5. 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

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)