fish2018/pansou · error
代理地址解析失败
Error message
代理地址解析失败: %w
What it means
applyProxy validates the proxy URL passed to NewHTTPClient before configuring the HTTP transport. This error is returned when Go's url.Parse cannot parse the raw proxy string (e.g. malformed syntax like control characters or invalid percent-encoding). The original parse error is wrapped with %w so it can be inspected with errors.Is/As.
Solutions
- Print/inspect the raw proxy string (use %q) to spot hidden whitespace or bad characters and fix the value.
- Validate the proxy with url.Parse in your own config-loading code before passing it to NewHTTPClient.
- Escape credentials in the URL with url.UserPassword(username, password) instead of string concatenation.
- If the proxy comes from an env var, trim whitespace: strings.TrimSpace(os.Getenv("HTTPS_PROXY")).
Example fix
// before
client, err := NewHTTPClient(WithProxy(os.Getenv("HTTPS_PROXY")))
// after
raw := strings.TrimSpace(os.Getenv("HTTPS_PROXY"))
if raw != "" {
if _, err := url.Parse(raw); err != nil {
return fmt.Errorf("invalid HTTPS_PROXY %q: %w", raw, err)
}
}
client, err := NewHTTPClient(WithProxy(raw)) Defensive patterns
Strategy: validation
Validate before calling
raw := strings.TrimSpace(cfg.Proxy)
if raw != "" {
if _, err := url.Parse(raw); err != nil {
return fmt.Errorf("invalid proxy URL %q: %w", raw, err)
}
} Try / catch
if err := NewHTTPClient(opts...); err != nil {
var perr *url.Error
if errors.As(err, &perr) {
// handle malformed proxy URL
}
return err
} Prevention
- Always trim proxy values read from env vars or config files.
- Store proxies in full 'scheme://host:port' form in configuration.
- Validate proxy URLs at config-load time, not at request time.
When it happens
Trigger: Calling NewHTTPClient with a proxy option string that url.Parse rejects, e.g. 'http://[::1:8080' (malformed bracket), a URL containing raw spaces or control characters, or invalid percent-escapes like 'http://proxy:%zz@host'.
Common situations: Proxy read from an env var (HTTP_PROXY/HTTPS_PROXY) or config file with a stray space or invisible character; hand-edited YAML/JSON config with a truncated URL; interpolating credentials containing reserved characters without escaping.
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/4bd7c04b0abd66fb.
Report an issue: GitHub.
Appendix: source
Thrown at util/http_util.go:84
// 创建客户端
client := &http.Client{
Transport: transport,
Timeout: time.Duration(60) * time.Second,
}
return client, nil
}
func applyProxy(transport *http.Transport, rawProxyURL string) error {
rawProxyURL = strings.TrimSpace(rawProxyURL)
if rawProxyURL == "" {
return nil
}
proxyURL, err := url.Parse(rawProxyURL)
if err != nil {
return fmt.Errorf("代理地址解析失败: %w", err)
}
if proxyURL.Scheme == "" || proxyURL.Host == "" {
return fmt.Errorf("代理地址必须包含协议和主机")
}
switch strings.ToLower(proxyURL.Scheme) {
case "socks5", "socks5h":
if proxyURL.Scheme == "socks5h" {
clone := *proxyURL
clone.Scheme = "socks5"
proxyURL = &clone
}
// 创建SOCKS5代理拨号器
dialer, err := proxy.FromURL(proxyURL, proxy.Direct)
if err != nil {
return fmt.Errorf("SOCKS5代理初始化失败: %w", err)
}View on GitHub (pinned to beaa561337)