fish2018/pansou · error

GET请求失败

Error message

GET请求失败: %w

What it means

xdpan's fetchSearchResults executes the search GET via doRequestWithRetry and wraps any transport error as 'GET请求失败: %w'. doRequestWithRetry already handles retries, so this error means the request exhausted retries and still failed — a persistent network, DNS, TLS, or timeout problem reaching the xdpan search endpoint.

Solutions

  1. Test connectivity to the site directly (curl -v the searchURL) to distinguish local network issues from site outages.
  2. Check DNS resolution and try an alternate resolver or mirror domain if the domain is polluted/unreachable.
  3. Verify proxy/VPN settings if the site is region-blocked from your network.
  4. If timeouts persist, check site latency and increase the 30s context timeout or reduce concurrency.
Defensive patterns

Strategy: retry

Validate before calling

if err := probeReachable(baseURL, 5*time.Second); err != nil { /* skip plugin, site unreachable */ }

Try / catch

results, err := pluginSearch(keyword)
if err != nil {
	if errors.Is(err, context.DeadlineExceeded) {
		// timed out — retry with longer deadline or skip
	} else if isConnRefusedOrDNS(err) {
		// network/DNS issue — fail over to alternate source
	}
}

Prevention

When it happens

Trigger: p.doRequestWithRetry returns an error after all retries: connection refused, DNS failure, TLS handshake error, context deadline exceeded (30s timeout), or connection reset while requesting baseURL/search?page=1&k=<keyword>&p=baidu.

Common situations: Site is down or blocked from the user's network/region; DNS pollution of the domain; corporate firewall blocks outbound requests; the 30-second timeout expires on a slow/unresponsive server; Cloudflare dropping non-browser TLS fingerprints.

Related errors


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

Appendix: source

Thrown at plugin/xdpan/xdpan.go:114

	searchURL := fmt.Sprintf("%s/search?page=1&k=%s&p=baidu", strings.TrimRight(p.baseURL, "/"), url.QueryEscape(keyword))

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
	if err != nil {
		return nil, fmt.Errorf("创建GET请求失败: %w", err)
	}

	p.setRequestHeaders(req)

	if DebugLog {
		fmt.Printf("[xdpan] 搜索URL: %s\n", searchURL)
	}

	resp, err := p.doRequestWithRetry(req, client)
	if err != nil {
		return nil, fmt.Errorf("GET请求失败: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("请求返回状态码: %d", resp.StatusCode)
	}

	// 解析HTML
	doc, err := goquery.NewDocumentFromReader(io.LimitReader(resp.Body, maxPageSize))
	if err != nil {
		return nil, fmt.Errorf("解析HTML失败: %w", err)
	}

	results := p.extractSearchResults(doc)
	if len(results) == 0 && doc.Find("title").First().Text() == "Just a moment..." {
		return nil, fmt.Errorf("站点触发 Cloudflare 浏览器验证")
	}
	return results, nil

View on GitHub (pinned to beaa561337)