xpzouying/xiaohongshu-mcp · error

download errors occurred: %v

Error message

download errors occurred: %v

What it means

DownloadImages downloads multiple images and aggregates per-image failures instead of failing on the first error. If any image download fails, it returns the successfully downloaded local paths plus a single wrapped error listing all individual failures. It is thrown to signal partial failure: some images may still be usable (returned in localPaths).

Source

Thrown at pkg/downloader/images.go:121

	return filePath, nil
}

// DownloadImages 批量下载图片
func (d *ImageDownloader) DownloadImages(imageURLs []string) ([]string, error) {
	var localPaths []string
	var errs []error

	for _, imageURL := range imageURLs {
		localPath, err := d.DownloadImage(imageURL)
		if err != nil {
			errs = append(errs, fmt.Errorf("failed to download %s: %w", imageURL, err))
			continue
		}
		localPaths = append(localPaths, localPath)
	}

	if len(errs) > 0 {
		return localPaths, fmt.Errorf("download errors occurred: %v", errs)
	}

	return localPaths, nil
}

// isValidImageURL 检查是否为有效的图片URL
func (d *ImageDownloader) isValidImageURL(rawURL string) bool {
	// 检查是否以http/https开头
	if !strings.HasPrefix(strings.ToLower(rawURL), "http://") &&
		!strings.HasPrefix(strings.ToLower(rawURL), "https://") {
		return false
	}

	// 检查URL格式
	parsedURL, err := url.Parse(rawURL)
	if err != nil {
		return false
	}

View on GitHub (pinned to 332d196854)

Solutions

  1. Inspect the wrapped %v error list to identify which URLs failed and verify each URL with a curl/HTTP GET to confirm accessibility
  2. Re-run download for only the failed URLs (localPaths already contains successful ones)
  3. Use IsImageURL to pre-filter malformed URLs before calling DownloadImages
  4. Add proxy configuration or retry with backoff for flaky remote hosts

Example fix

// before
localPaths, err := downloader.DownloadImages(ctx, urls)
if err != nil {
    return err // loses the successful paths
}
// after
localPaths, err := downloader.DownloadImages(ctx, urls)
if err != nil {
    log.Warnf("partial download: %v", err) // localPaths still has succeeded images
    if len(localPaths) == 0 { return err }
}
Defensive patterns

Strategy: try-catch

Validate before calling

for _, u := range urls {
    if !IsImageURL(u) { return fmt.Errorf("invalid image url: %s", u) }
}
resp, err := http.Head(u)
if err != nil || resp.StatusCode >= 400 { return fmt.Errorf("unreachable: %s", u) }

Type guard

func isDownloadableImage(u string) bool {
    if !IsImageURL(u) { return false }
    resp, err := http.Head(u)
    return err == nil && resp.StatusCode < 400
}

Try / catch

localPaths, err := downloader.DownloadImages(ctx, urls)
if err != nil {
    var dlErr = fmt.Sprintf("%v", err)
    log.Printf("partial downloads, failed set: %s", dlErr)
    if len(localPaths) == 0 {
        return fmt.Errorf("all images failed to download: %w", err)
    }
    // proceed with partial results
}

Prevention

When it happens

Trigger: Calling DownloadImages with one or more URLs that fail to download (network error, HTTP non-200, timeout, invalid image URL filtered upstream). Any failed item is appended to errs, and the aggregate error is returned at the end of the loop.

Common situations: Batch-processing article/Markdown content where some remote image hosts are dead, rate-limited, or blocking hotlinking; expired CDN URLs; DNS failures in restricted network environments.

Related errors


AI-assisted analysis of xpzouying/xiaohongshu-mcp@332d196854 (2026-09-05). Data as JSON: /api/errors/31fad8b4fb1333cf. Report an issue: GitHub.