flipped-aurora/gin-vue-admin · error

下载压缩包失败: %w

Error message

下载压缩包失败: %w

What it means

The second hop — http.Get on the real zip download URL returned by the marketplace — failed at the transport level. Note this URL is server-controlled output; failures include DNS errors, TLS errors, connection refused/timeouts, and also http.Get's built-in rejection of non-http(s) schemes (it returns 'unsupported protocol scheme').

Source

Thrown at server/service/system/sys_skills.go:439

	}

	var meta struct {
		Data struct {
			URL string `json:"url"`
		} `json:"data"`
	}
	if err = json.Unmarshal(metaBody, &meta); err != nil {
		return fmt.Errorf("解析下载结果失败: %w", err)
	}

	realDownloadURL := strings.TrimSpace(meta.Data.URL)
	if realDownloadURL == "" {
		return errors.New("下载结果缺少 url")
	}

	zipResp, err := http.Get(realDownloadURL)
	if err != nil {
		return fmt.Errorf("下载压缩包失败: %w", err)
	}
	defer zipResp.Body.Close()

	if zipResp.StatusCode != http.StatusOK {
		return fmt.Errorf("下载压缩包失败, HTTP状态码: %d", zipResp.StatusCode)
	}

	tmpFile, err := os.CreateTemp("", "gva-skill-*.zip")
	if err != nil {
		return fmt.Errorf("创建临时文件失败: %w", err)
	}
	tmpPath := tmpFile.Name()
	defer os.Remove(tmpPath)

	if _, err = io.Copy(tmpFile, zipResp.Body); err != nil {
		tmpFile.Close()
		return fmt.Errorf("保存技能包失败: %w", err)
	}

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Log the wrapped net error and the realDownloadURL to see which host/scheme failed
  2. Confirm the server can reach the returned host (curl -v <url>)
  3. If the marketplace returns an unsupported scheme, validate it before calling http.Get
  4. Add proxy configuration or allowlist the CDN/object-storage domain in egress rules
Defensive patterns

Strategy: retry

Validate before calling

u, err := url.Parse(realDownloadURL)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") {
    // reject bad scheme before http.Get (avoids 'unsupported protocol scheme')
}
if host := u.Host; host != "" {
    if c, e := net.DialTimeout("tcp", host+":443", 5*time.Second); e != nil { /* unreachable */ } else { c.Close() }
}

Type guard

func isDownloadableURL(raw string) bool {
    u, err := url.Parse(raw)
    return err == nil && (u.Scheme == "https" || u.Scheme == "http") && u.Host != ""
}

Try / catch

if err := DownloadOnlineSkill(ctx, req); err != nil && strings.Contains(err.Error(), "下载压缩包失败:") {
    // transport failure on the zip URL; check egress/DNS for the returned host and retry
}

Prevention

When it happens

Trigger: Calling DownloadOnlineSkill when the returned real download URL points to a host that's unreachable, uses a non-http scheme, or the server lacks egress to it (e.g. internal/OSS URL not reachable from the server's network).

Common situations: Marketplace returns an object-storage URL blocked by the server's firewall; no DNS for the CDN host; URL scheme mismatch; China-network reachability issues with the CDN.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/1a5c686b64e64853. Report an issue: GitHub.