fish2018/pansou · error

发送搜索请求失败

Error message

发送搜索请求失败: %w

What it means

searchImpl in the leijing plugin wraps any error from p.doRequest (which performs the HTTP GET against the search URL) with this message. It signals the HTTP request itself failed before a response was obtained. The original transport error is preserved via %w.

Solutions

  1. Inspect the wrapped cause from %w to see the transport-level reason
  2. Test the search URL with curl from the same host to confirm reachability
  3. Increase the HTTP client timeout or configure a proxy if egress is restricted
  4. Check if the site blocks automated clients and adjust headers (User-Agent, Referer)
  5. If the domain changed, update the BaseURL/searchURL constants in the plugin
Defensive patterns

Strategy: try-catch

Validate before calling

u, err := url.Parse(searchURL)
if err != nil || u.Host == "" {
    return fmt.Errorf("invalid search URL: %q", searchURL)
}

Try / catch

results, err := plugin.Search(ctx, keyword)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        return fmt.Errorf("leso search timed out: %w", err)
    }
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() {
        // retry with a longer timeout
    }
    return err
}

Prevention

When it happens

Trigger: p.doRequest(client, searchURL, BaseURL) returns a non-nil error during a keyword search: connection refused/reset, timeout, DNS failure, TLS error, or proxy failure.

Common situations: The leijing upstream site is unreachable or has changed domain; corporate firewall blocks egress; client timeout too short; site requires different TLS settings (e.g. TLS fingerprinting blocked Go's default client).

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

Appendix: source

Thrown at plugin/leijing/leijing.go:132

		log.Printf("[Leijing] 响应状态: %d", resp.StatusCode)
	}
	
	return resp, nil
}

// searchImpl 实际的搜索实现
func (p *LeijingPlugin) searchImpl(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
	searchURL := fmt.Sprintf("%s%s?keyword=%s", BaseURL, SearchPath, url.QueryEscape(keyword))
	
	if p.debugMode {
		log.Printf("[Leijing] 开始搜索: %s", keyword)
		log.Printf("[Leijing] 搜索URL: %s", searchURL)
	}
	
	// 发送搜索请求
	resp, err := p.doRequest(client, searchURL, BaseURL)
	if err != nil {
		return nil, fmt.Errorf("发送搜索请求失败: %w", err)
	}
	defer resp.Body.Close()
	
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("搜索响应状态码异常: %d", resp.StatusCode)
	}
	
	// 处理响应体(可能是gzip压缩的)
	reader, err := p.getResponseReader(resp)
	if err != nil {
		return nil, err
	}
	
	// 解析HTML
	doc, err := goquery.NewDocumentFromReader(reader)
	if err != nil {
		return nil, fmt.Errorf("解析HTML失败: %w", err)
	}

View on GitHub (pinned to beaa561337)