fish2018/pansou · error

创建POST请求失败

Error message

创建POST请求失败: %w

What it means

postSearchRequest builds the http POST request with http.NewRequestWithContext and wraps any construction failure. Because the URL and body are assembled from earlier parsing, this almost always means the target URL was malformed (e.g. invalid characters from parsed form data) or the context was already invalid.

Solutions

  1. Print/log the searchURL and postData just before http.NewRequestWithContext to spot malformed values
  2. Validate searchURL with url.Parse before constructing the request
  3. Fix the BaseURL constant to a clean, valid absolute URL (no spaces/BOM)
  4. url.PathEscape/url.QueryEscape user-supplied keyword pieces
  5. Ensure the encoded postData is passed via strings.NewReader with correct Content-Type

Example fix

// before
req, err := http.NewRequestWithContext(ctx, "POST", searchURL, strings.NewReader(postData))
if err != nil {
    return "", fmt.Errorf("创建POST请求失败: %w", err)
}
// after
if _, err := url.Parse(searchURL); err != nil {
    return "", fmt.Errorf("invalid search URL %q: %w", searchURL, err)
}
req, err := http.NewRequestWithContext(ctx, "POST", searchURL, strings.NewReader(postData))
if err != nil {
    return "", fmt.Errorf("创建POST请求失败: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

_, err := plugin.Search(ctx, keyword)
var urlErr *url.Error
if errors.As(err, &urlErr) {
    // malformed URL in request construction
}

Prevention

When it happens

Trigger: searchURL passed to http.NewRequestWithContext fails URL parsing — typically when the BaseURL constant or the encoded form data contains characters that make an invalid URL (spaces, control chars, bad percent-encoding).

Common situations: BaseURL configured/edited incorrectly with typos or trailing whitespace; keyword contains characters that break url.Values encoding in an unexpected way; plugin version where BaseURL was changed to a bad value.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at plugin/qupanshe/qupanshe.go:235

// postSearchRequest 发送POST请求获取搜索结果URL
func (p *QupanshePlugin) postSearchRequest(client *http.Client, keyword, formhash string) (string, error) {
	// 添加延时,避免请求过快
	time.Sleep(2 * time.Second)

	// 构建POST请求
	searchURL := fmt.Sprintf("%s/search.php?mod=forum", BaseURL)
	data := url.Values{}
	data.Set("formhash", formhash)
	data.Set("srchtxt", keyword)
	data.Set("searchsubmit", "yes")

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

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

	p.setRequestHeaders(req)
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	// 详细日志:请求信息
	if DebugLog {
		fmt.Printf("[qupanshe] POST请求URL: %s\n", searchURL)
		fmt.Printf("[qupanshe] POST请求数据: %s\n", postData)
		fmt.Printf("[qupanshe] POST请求头:\n")
		for key, values := range req.Header {
			for _, value := range values {
				fmt.Printf("  %s: %s\n", key, value)
			}
		}
		
		// 显示将要发送的cookies
		if client.Jar != nil {

View on GitHub (pinned to beaa561337)