fish2018/pansou · error

[ ] 请求搜索页面失败

Error message

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

What it means

Returned by doSearch in the aikanzy plugin when the retrying HTTP client (p.doRequestWithRetry) fails to send the search request at all — no response was obtained. All underlying transport errors (connection refused, DNS, timeout, TLS) are wrapped here with the plugin name prefix.

Solutions

  1. Unwrap the error to identify the transport cause (timeout vs connection refused vs TLS).
  2. Confirm the site's current domain is correct and reachable (curl -v).
  3. Increase defaultTimeout if requests time out on slow connections.
  4. Add or update a proxy configuration if the site is blocked in your network.
  5. If TLS errors occur, verify system CA certificates are up to date.

Example fix

// before
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
	return nil, fmt.Errorf("[%s] 请求搜索页面失败: %w", p.Name(), err)
}
// after
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
	var netErr net.Error
	if errors.As(err, &netErr) && netErr.Timeout() {
		return nil, fmt.Errorf("[%s] search request timed out (increase defaultTimeout or use proxy): %w", p.Name(), err)
	}
	return nil, fmt.Errorf("[%s] 请求搜索页面失败: %w", p.Name(), err)
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight check before searching
resp, err := http.Head(baseURL)
if err != nil {
	return fmt.Errorf("source site unreachable: %w", err)
}
resp.Body.Close()

Try / catch

resp, err := p.doRequestWithRetry(req, client)
if err != nil {
	var dnsErr *net.DNSError
	if errors.As(err, &dnsErr) {
		// wrong/dead domain — refresh base URL
	}
	if errors.Is(err, context.DeadlineExceeded) {
		// timeout — raise timeout or add proxy, then retry
	}
	return err
}

Prevention

When it happens

Trigger: After the request is built with browser-like headers, p.doRequestWithRetry(req, client) exhausts its attempts because client.Do returns an error each time (site unreachable, TLS handshake failure, context deadline exceeded from defaultTimeout).

Common situations: The aikanzy site is down or its domain has changed; corporate firewall/GFW blocks the site; the per-request context times out on slow links; TLS certificate mismatch after the site migrates hosts.

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/bbadd356a079e3ca. Report an issue: GitHub.

Appendix: source

Thrown at plugin/aikanzy/aikanzy.go:162

	// 创建请求
	req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
	if err != nil {
		return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
	}
	
	// 设置完整的请求头(避免反爬虫)
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
	req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Referer", "https://www.aikanzy.com/")
	req.Header.Set("Upgrade-Insecure-Requests", "1")
	req.Header.Set("Cache-Control", "max-age=0")
	
	// 使用带重试的请求方法发送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 != http.StatusOK {
		return nil, fmt.Errorf("[%s] 请求搜索页面失败,状态码: %d", p.Name(), resp.StatusCode)
	}
	
	// 使用goquery解析HTML
	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("[%s] 解析HTML失败: %w", p.Name(), err)
	}
	
	// 解析搜索结果列表
	articleItems := p.parseArticleList(doc)
	if len(articleItems) == 0 {
		return []model.SearchResult{}, nil

View on GitHub (pinned to beaa561337)