fish2018/pansou · error

[ ] 搜索请求失败

Error message

[%s] 搜索请求失败: %w

What it means

The wuji plugin's searchPage wraps the error from doRequestWithRetry, which performs the HTTP GET (with up to MaxRetries=3 attempts). Any transport-level failure — DNS resolution, TCP connect, TLS handshake, or the 30s context timeout — surfaces here wrapped with the plugin name. This is a client-side/network error, not an HTTP status problem (status codes are handled separately).

Solutions

  1. Check the wrapped error text to distinguish timeout vs connection-refused vs DNS failure
  2. Verify the host can reach https://xcili.net (curl -v from the same machine/container)
  3. Increase TimeoutSeconds or MaxRetries if the site is merely slow
  4. Configure a proxy for restricted networks (HTTP_PROXY/HTTPS_PROXY) or use a mirror
  5. If the site is permanently dead, disable the wuji plugin
Defensive patterns

Strategy: retry

Validate before calling

conn, err := net.DialTimeout("tcp", "xcili.net:443", 5*time.Second)
if err != nil {
    return fmt.Errorf("wuji upstream unreachable: %w", err)
}
conn.Close()

Try / catch

results, err := p.Search(keyword, ext)
if err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() {
        // retry with backoff or fall back to another plugin
    } else if strings.Contains(err.Error(), "搜索请求失败") {
        log.Printf("wuji transport error: %v", err)
    }
}

Prevention

When it happens

Trigger: p.doRequestWithRetry(req, client) returns an error after exhausting retries: site unreachable, DNS failure, TLS errors, connection refused/reset, or ctx deadline (TimeoutSeconds=30) exceeded.

Common situations: xcili.net is down, blocked, or geo-restricted from the server running pansou; no outbound internet or broken DNS in a container; corporate firewall/proxy blocking the domain; slow site responses exceeding the 30s timeout repeatedly.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at plugin/wuji/wuji.go:191

	searchURL := fmt.Sprintf(SearchURL, encodedKeyword, page)
	
	// 创建带超时的上下文
	ctx, cancel := context.WithTimeout(context.Background(), TimeoutSeconds*time.Second)
	defer cancel()
	
	// 创建请求
	req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
	if err != nil {
		return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
	}
	
	// 设置请求头
	p.setRequestHeaders(req)
	
	// 发送HTTP请求
	resp, err := p.doRequestWithRetry(req, client)
	if err != nil {
		return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
	}
	defer resp.Body.Close()
	
	// 检查状态码
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
	}
	
	// 读取响应体内容
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("[%s] 读取响应失败: %w", p.Name(), err)
	}
	
	// 解析HTML
	doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body)))
	if err != nil {
		return nil, fmt.Errorf("[%s] HTML解析失败: %w", p.Name(), err)

View on GitHub (pinned to beaa561337)