fish2018/pansou · error

[ ] hsid= 创建链接请求失败

Error message

[%s] hsid=%s创建链接请求失败: %w

What it means

This error is thrown by fetchShareLink when http.NewRequestWithContext fails to construct the GET request for converting a hsid into a share link. This is rare — it usually means the fetchURL was malformed (invalid method/URL) or the 15s-timeout context was already expired/invalid before the request was created.

Solutions

  1. Log fetchURL when this fires and validate it with url.Parse before constructing the request
  2. url.PathEscape / url.QueryEscape the hsid before interpolating it into fetchURL
  3. Check that hsid is non-empty before calling fetchShareLink
  4. Use context.WithTimeout on a caller-supplied context rather than Background so cancellation is traceable

Example fix

// before
req, err := http.NewRequestWithContext(ctx, "GET", fetchURL, nil)
if err != nil {
	return "", "", fmt.Errorf("[%s] hsid=%s创建链接请求失败: %w", p.Name(), hsid, err)
}
// after
if hsid == "" {
	return "", "", fmt.Errorf("[%s] hsid为空,无法创建链接请求", p.Name())
}
if _, perr := url.Parse(fetchURL); perr != nil {
	return "", "", fmt.Errorf("[%s] fetchURL非法 (%s): %w", p.Name(), fetchURL, perr)
}
req, err := http.NewRequestWithContext(ctx, "GET", fetchURL, nil)
if err != nil {
	return "", "", fmt.Errorf("[%s] hsid=%s创建链接请求失败: %w", p.Name(), hsid, err)
}
Defensive patterns

Strategy: validation

Validate before calling

if hsid == "" {
	return errors.New("hsid is empty")
}
if _, err := url.Parse(fetchURL); err != nil {
	return fmt.Errorf("invalid fetchURL %q: %w", fetchURL, err)
}

Try / catch

req, err := http.NewRequestWithContext(ctx, "GET", fetchURL, nil)
if err != nil {
	return fmt.Errorf("build request failed for hsid=%s: %w", hsid, err)
}

Prevention

When it happens

Trigger: http.NewRequestWithContext(ctx, "GET", fetchURL, nil) returns an error inside fetchShareLink — typically because fetchURL fails url.Parse or the context is invalid.

Common situations: The hsid or platform value interpolated into fetchURL contains characters that break the URL; fetchURL built with an empty hsid; caller-provided context already cancelled; URL containing spaces or unencoded Chinese characters.

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

Appendix: source

Thrown at plugin/haisou/haisou.go:390

}

// fetchShareLink 通过hsid获取具体的分享链接
func (p *HaisouPlugin) fetchShareLink(client *http.Client, hsid string, platform string) (string, string, error) {
	// 构建获取链接的URL
	fetchURL := fmt.Sprintf("https://haisou.cc/api/pan/share/%s/fetch", hsid)

	if DebugLog {
		fmt.Printf("[%s] 获取链接 hsid=%s platform=%s: %s\n", p.Name(), hsid, platform, fetchURL)
	}

	// 创建带超时的上下文
	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
	defer cancel()

	// 创建请求对象
	req, err := http.NewRequestWithContext(ctx, "GET", fetchURL, nil)
	if err != nil {
		return "", "", fmt.Errorf("[%s] hsid=%s创建链接请求失败: %w", p.Name(), hsid, 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", "application/json, text/plain, */*")
	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://haisou.cc/")

	// 发送HTTP请求(带重试机制)
	resp, err := p.doRequestWithRetry(req, client)
	if err != nil {
		return "", "", fmt.Errorf("[%s] hsid=%s链接请求失败: %w", p.Name(), hsid, err)
	}
	defer resp.Body.Close()

	// 检查状态码
	if resp.StatusCode != 200 {

View on GitHub (pinned to beaa561337)