fish2018/pansou · error

[ ] 创建请求失败

Error message

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

What it means

http.NewRequestWithContext failed while building the POST request to the API URL. This occurs before any network I/O and almost always means the URL failed to parse or the body/io.Reader itself errored.

Solutions

  1. Print/validate apiURL before constructing the request (url.Parse the constant at init)
  2. Check the wrapped error's message for 'parse ...: invalid ...' hints
  3. Fix the configuration or constant supplying apiURL

Example fix

// before
req, err := http.NewRequestWithContext(ctx, "POST", apiURL, bytes.NewBuffer(jsonData))
// after
if _, perr := url.Parse(apiURL); perr != nil {
    return nil, fmt.Errorf("无效的API地址 %q: %w", apiURL, perr)
}
req, err := http.NewRequestWithContext(ctx, "POST", apiURL, bytes.NewBuffer(jsonData))
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(apiURL)
if err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("无效的API地址: %q", apiURL)
}

Try / catch

req, err := http.NewRequestWithContext(ctx, "POST", apiURL, bytes.NewBuffer(jsonData))
if err != nil {
    return nil, fmt.Errorf("[%s] 创建请求失败: %w", pluginName, err)
}

Prevention

When it happens

Trigger: apiURL is malformed (bad scheme, spaces, control characters) or the request body reader returns an error when NewRequest reads it into memory.

Common situations: apiURL built from an empty or misconfigured base URL; configuration containing whitespace or invalid characters interpolated into the URL; constant leaked into apiURL.

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

Appendix: source

Thrown at plugin/xdyh/xdyh.go:136

		MaxWorkers: 10,   // API默认并发数
		SaveToFile: false,
		SplitLinks: true,
	}
	
	// 3. JSON序列化
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		return nil, fmt.Errorf("[%s] JSON序列化失败: %w", pluginName, err)
	}
	
	// 4. 创建带超时的上下文
	ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout)
	defer cancel()
	
	// 5. 创建请求
	req, err := http.NewRequestWithContext(ctx, "POST", apiURL, bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("[%s] 创建请求失败: %w", pluginName, err)
	}
	
	// 6. 设置请求头
	p.setRequestHeaders(req)
	
	// 7. 发送请求
	resp, err := p.doRequestWithRetry(req, client)
	if err != nil {
		return nil, fmt.Errorf("[%s] 搜索请求失败: %w", pluginName, err)
	}
	defer resp.Body.Close()
	
	// 8. 检查状态码
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("[%s] 请求返回状态码: %d", pluginName, resp.StatusCode)
	}
	
	// 9. 读取响应体

View on GitHub (pinned to beaa561337)