flipped-aurora/gin-vue-admin · error

构造请求失败: %w

Error message

构造请求失败: %w

What it means

runHTTP builds the http.Request with http.NewRequest. If request construction fails (invalid method token, unparsable URL at request-build stage), it wraps the error as 构造请求失败. The task never reaches the network in this case.

Source

Thrown at server/service/system/sys_timed_task_runner.go:144

func (s *TimedTaskService) runHTTP(t system.SysTimedTask) (string, error) {
	u, err := url.Parse(t.HttpUrl)
	if err != nil {
		return "", fmt.Errorf("URL 非法: %w", err)
	}
	if u.Scheme != "http" && u.Scheme != "https" {
		return "", fmt.Errorf("仅允许 http/https, 实际为 %q", u.Scheme)
	}
	method := strings.ToUpper(strings.TrimSpace(t.HttpMethod))
	if method == "" {
		method = http.MethodGet
	}
	var body io.Reader
	if t.HttpBody != "" {
		body = strings.NewReader(t.HttpBody)
	}
	req, err := http.NewRequest(method, t.HttpUrl, body)
	if err != nil {
		return "", fmt.Errorf("构造请求失败: %w", err)
	}
	if len(t.HttpHeader) > 0 {
		var hdr map[string]string
		if err := json.Unmarshal(t.HttpHeader, &hdr); err != nil {
			return "", fmt.Errorf("http_header 必须是 JSON 对象: %w", err)
		}
		for k, v := range hdr {
			req.Header.Set(k, v)
		}
	}

	client := newTimedTaskHTTPClient(t.HttpAllowPrivate, defaultHTTPTimeout)
	resp, err := client.Do(req)
	if err != nil {
		var uerr *url.Error
		if errors.As(err, &uerr) && uerr.Timeout() {
			return "", errTaskTimeout
		}

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Fix t.HttpMethod to a valid HTTP verb (GET, POST, PUT, DELETE, PATCH... or empty for default GET)
  2. Inspect the wrapped %w error for the precise NewRequest cause and correct the corresponding field
  3. Validate/sanitize method input in the task-creation API

Example fix

// before
HttpMethod: "POST JSON"
// after
HttpMethod: "POST"
Defensive patterns

Strategy: validation

Validate before calling

method := strings.ToUpper(strings.TrimSpace(httpMethod))
valid := map[string]bool{"GET":true,"POST":true,"PUT":true,"DELETE":true,"PATCH":true,"HEAD":true,"OPTIONS":true}
if method != "" && !valid[method] {
    return fmt.Errorf("invalid HTTP method: %s", method)
}

Type guard

func isValidMethod(m string) bool {
    switch strings.ToUpper(strings.TrimSpace(m)) {
    case "", "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS":
        return true
    }
    return false
}

Try / catch

if err := RunTask(t); err != nil {
    if strings.Contains(err.Error(), "构造请求失败") {
        log.Warnf("task %d failed request construction: %v", t.ID, err)
    }
}

Prevention

When it happens

Trigger: t.HttpMethod contains characters invalid in an HTTP method token (spaces, non-ASCII); URL valid to url.Parse but rejected by NewRequest (e.g. malformed host); body reader construction issues.

Common situations: Typo in method field like 'GET ' with a trailing character or lowercase custom verbs containing spaces; corrupted http_method column data from an import.

Related errors


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