fish2018/pansou · error

创建下载链接请求失败

Error message

创建下载链接请求失败: %w

What it means

In getDownloadLinks, http.NewRequestWithContext failed to construct the GET request for the post's download URL. This is a pre-network failure meaning the downloadURL string is malformed — usually derived from a post field (link/guid) that is empty or not a valid URL.

Solutions

  1. Validate the downloadURL with url.Parse (scheme and host required) before creating the request and skip posts with invalid links.
  2. Log the offending URL in the error to identify which post produced it.
  3. Ensure the field used to build downloadURL is non-empty and absolute; fall back to another field (e.g. post.link) if empty.
  4. Escape or sanitize any user/post-derived path segments before concatenation.

Example fix

// before
req, err := http.NewRequestWithContext(ctx, "GET", downloadURL, nil)
if err != nil {
    return nil, fmt.Errorf("创建下载链接请求失败: %w", err)
}
// after
u, perr := url.Parse(downloadURL)
if perr != nil || u.Scheme == "" || u.Host == "" {
    return nil, fmt.Errorf("无效的下载链接: %q (%v)", downloadURL, perr)
}
req, err := http.NewRequestWithContext(ctx, "GET", downloadURL, nil)
if err != nil {
    return nil, fmt.Errorf("创建下载链接请求失败: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(downloadURL)
if err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("跳过无效下载链接: %q", downloadURL)
}

Try / catch

links, err := getDownloadLinks(ctx, post)
if err != nil && strings.Contains(err.Error(), "创建下载链接请求失败") {
    // invalid URL from this post: skip it and continue with other results
}

Prevention

When it happens

Trigger: Called (via an anonymous goroutine/callback that fetches download links for a search result) with a downloadURL built from a CygPost field that http.NewRequestWithContext cannot parse — empty link, relative URL, or URL with invalid characters.

Common situations: A post in the search results has an empty or relative link field; upstream changed the field containing the download path; the URL was constructed by string concatenation without url.Parse validation.

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

Appendix: source

Thrown at plugin/cyg/cyg.go:231

		results = append(results, result)
	}

	return results
}

// getDownloadLinks 获取指定帖子的下载链接
func (p *CygPlugin) getDownloadLinks(client *http.Client, postID int) ([]model.Link, error) {
	// 构建下载链接获取URL
	downloadURL := fmt.Sprintf(cygBaseURL+"/wp-json/acg-studio/v1/download?id=%d", postID)

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

	// 创建请求对象
	req, err := http.NewRequestWithContext(ctx, "GET", downloadURL, nil)
	if err != nil {
		return nil, fmt.Errorf("创建下载链接请求失败: %w", err)
	}

	// 设置请求头
	p.setRequestHeaders(req)

	// 发送请求
	resp, err := p.doRequestWithRetry(req, client)
	if err != nil {
		return nil, fmt.Errorf("下载链接请求失败: %w", err)
	}
	defer resp.Body.Close()

	// 检查状态码
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("下载链接请求状态码: %d", resp.StatusCode)
	}

	// 解析响应

View on GitHub (pinned to beaa561337)