fish2018/pansou · error

获取searchid失败

Error message

获取searchid失败: %v

What it means

ClxiongPlugin.SearchWithResult fails in its first phase: p.getSearchID(keyword) could not obtain the searchid token needed for the two-step search (POST to get a 302 redirect whose Location header carries the searchid, then GET results). The underlying cause is wrapped with %v (loses errors.Is/As chains) and, when debugMode is on, also logged. Without a searchid the second GET cannot proceed, so Search fails entirely.

Solutions

  1. Enable debugMode or inspect the wrapped error to see the underlying cause (transport failure vs unexpected status).
  2. If the inner error is "期望302重定向" with a 200 status, the site likely changed flow or is serving an anti-bot page — capture the response body and update getSearchID accordingly.
  3. Check connectivity and rate limits; slow down request frequency if 429 appears.
  4. Increase timeouts/retries in getSearchID if the POST intermittently times out.
  5. Prefer %w over %v when wrapping so callers can use errors.Is on the root cause.

Example fix

// before
return nil, fmt.Errorf("获取searchid失败: %v", err)
// after
return nil, fmt.Errorf("获取searchid失败: %w", err) // enables errors.Is/As on the root cause
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure keyword is usable before the two-step flow
if strings.TrimSpace(keyword) == "" { return nil, errors.New("keyword required") }

Try / catch

results, err := plugin.Search(ctx, keyword)
if err != nil {
    if strings.Contains(err.Error(), "获取searchid失败") {
        // first phase failed: check wrapped cause; retry once after backoff
        time.Sleep(2 * time.Second)
        results, err = plugin.Search(ctx, keyword)
    }
    if err != nil { return nil, err }
}

Prevention

When it happens

Trigger: Search -> SearchWithResult -> getSearchID returns an error: the POST timed out, connection failed, retry budget exhausted, or the server responded with a status other than 301/302 (or an empty Location header). SearchWithResult then returns fmt.Errorf("获取searchid失败: %v", err).

Common situations: The clxiong endpoint stopped issuing 302 redirects after a site update; anti-bot protection returns 200 with a challenge page instead of a redirect; rate limiting returns 429; the environment cannot reach the site (offline/CI).

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/99d5ba79ee02bc73. Report an issue: GitHub.

Appendix: source

Thrown at plugin/clxiong/clxiong.go:71

	if err != nil {
		return nil, err
	}
	return result.Results, nil
}

// SearchWithResult 搜索并返回详细结果
func (p *ClxiongPlugin) SearchWithResult(keyword string, ext map[string]interface{}) (*model.PluginSearchResult, error) {
	if p.debugMode {
		log.Printf("[CLXIONG] 开始搜索: %s", keyword)
	}

	// 第一步:POST搜索获取searchid
	searchID, err := p.getSearchID(keyword)
	if err != nil {
		if p.debugMode {
			log.Printf("[CLXIONG] 获取searchid失败: %v", err)
		}
		return nil, fmt.Errorf("获取searchid失败: %v", err)
	}

	// 第二步:GET搜索结果
	results, err := p.getSearchResults(searchID, keyword)
	if err != nil {
		if p.debugMode {
			log.Printf("[CLXIONG] 获取搜索结果失败: %v", err)
		}
		return nil, err
	}

	// 第三步:同步获取详情页磁力链接
	results = p.fetchDetailLinksSync(results)

	if p.debugMode {
		log.Printf("[CLXIONG] 搜索完成,获得 %d 个结果", len(results))
	}

View on GitHub (pinned to beaa561337)