flipped-aurora/gin-vue-admin · warning

构建下载请求失败: %w

Error message

构建下载请求失败: %w

What it means

DownloadOnlineSkill serializes {plugin_id, version} to JSON before POSTing to the skill marketplace. json.Marshal on a map[string]interface{} with string values essentially never fails, so this wrap is a defensive guard; it fires only if a value in the map cannot be marshaled (e.g. a channel, func, or unsupported type injected into the map).

Source

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

		if err := writeConstraint(tool, req.Content); err != nil {
			return err
		}
	}
	return nil
}

func (s *SkillsService) DownloadOnlineSkill(_ context.Context, req request.DownloadOnlineSkillReq) error {
	skillsDir, err := s.toolSkillsDir(req.Tool)
	if err != nil {
		return err
	}

	body, err := json.Marshal(map[string]interface{}{
		"plugin_id": req.ID,
		"version":   req.Version,
	})
	if err != nil {
		return fmt.Errorf("构建下载请求失败: %w", err)
	}

	downloadReq, err := http.NewRequest(http.MethodPost, "https://plugin.gin-vue-admin.com/api/shopPlugin/downloadSkill", bytes.NewReader(body))
	if err != nil {
		return fmt.Errorf("构建下载请求失败: %w", err)
	}
	downloadReq.Header.Set("Content-Type", "application/json")

	downloadResp, err := http.DefaultClient.Do(downloadReq)
	if err != nil {
		return fmt.Errorf("下载技能失败: %w", err)
	}
	defer downloadResp.Body.Close()

	if downloadResp.StatusCode != http.StatusOK {
		return fmt.Errorf("下载技能失败, HTTP状态码: %d", downloadResp.StatusCode)
	}

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Check the wrapped %v message for 'unsupported type' to find the offending field
  2. Keep req.ID and req.Version as plain strings and convert before building the map
  3. Implement json.Marshaler on any custom type placed into the payload

Example fix

// before
"plugin_id": req.ID, // ID became chan string after a refactor
// after
"plugin_id": fmt.Sprintf("%v", req.ID), // ensure serializable primitives
Defensive patterns

Strategy: validation

Validate before calling

payload := map[string]interface{}{"plugin_id": req.ID, "version": req.Version}
if _, err := json.Marshal(payload); err != nil {
    // reject before calling the service
}

Type guard

func isJSONSerializable(v interface{}) bool { _, err := json.Marshal(v); return err == nil }

Try / catch

if err := DownloadOnlineSkill(ctx, req); err != nil {
    if strings.Contains(err.Error(), "unsupported type") {
        // marshal bug in payload construction, fix the map values
    }
}

Prevention

When it happens

Trigger: Practically unreachable with the current hardcoded map of two string fields; would fire only if req.ID or req.Version were changed to an unmarshalable type, or the map construction were modified to include unsupported values.

Common situations: Code changes introducing a non-serializable value (func/chan/custom type without MarshalJSON) into the request map.

Related errors


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