fish2018/pansou · error

[ ] 创建请求失败

Error message

[%s] 创建请求失败: %w

What it means

Returned by doSearch in the aikanzy plugin when http.NewRequestWithContext fails to construct the GET request for the search URL. This happens before any network I/O and almost always means the URL string is malformed (parse error), since method/body are constant. The construction error is wrapped with %w.

Solutions

  1. Log/print the searchURL on failure to spot the malformed URL.
  2. Ensure the base URL includes a valid scheme (https://) and host.
  3. Escape the keyword with url.QueryEscape before appending it to the URL.
  4. Validate the final URL with url.Parse before calling http.NewRequestWithContext.

Example fix

// before
searchURL := baseURL + "/search/" + keyword
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
// after
searchURL := baseURL + "/search/" + url.QueryEscape(keyword)
if _, perr := neturl.Parse(searchURL); perr != nil {
	return nil, fmt.Errorf("invalid search URL %q: %w", searchURL, perr)
}
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
Defensive patterns

Strategy: validation

Validate before calling

u, err := neturl.Parse(searchURL)
if err != nil || u.Scheme == "" || u.Host == "" {
	return fmt.Errorf("invalid search URL: %q", searchURL)
}
// ensure keyword is escaped: url.QueryEscape(keyword)

Try / catch

req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
	log.Printf("request build failed for URL %q: %v", searchURL, err)
	return err
}

Prevention

When it happens

Trigger: p.doSearch builds searchURL (base URL + query params) and passes it to http.NewRequestWithContext; http.NewRequest returns an error because the URL cannot be parsed (e.g. control characters, bad scheme, unescaped invalid chars from user keyword interpolation).

Common situations: The configured base URL has a typo (missing scheme like 'https://'); the search keyword contains characters that were not url.QueryEscape'd; an env/config override sets an empty or invalid URL.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at plugin/aikanzy/aikanzy.go:147

	// 使用优化的客户端
	if p.optimizedClient != nil {
		client = p.optimizedClient
	}
	
	// 对关键词进行URL编码
	encodedKeyword := url.QueryEscape(keyword)
	
	// 构建搜索URL
	searchURL := fmt.Sprintf(searchURLTemplate, encodedKeyword)
	
	// 创建一个带有超时的上下文
	ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout*time.Second)
	defer cancel()
	
	// 创建请求
	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()
	

View on GitHub (pinned to beaa561337)