{"record":{"id":"7195e015865028a4","repo":"flipped-aurora/gin-vue-admin","slug":"w-7195e0","errorCode":null,"errorMessage":"构造请求失败: %w","messagePattern":"构造请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_timed_task_runner.go","lineNumber":144,"sourceCode":"func (s *TimedTaskService) runHTTP(t system.SysTimedTask) (string, error) {\n\tu, err := url.Parse(t.HttpUrl)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"URL 非法: %w\", err)\n\t}\n\tif u.Scheme != \"http\" && u.Scheme != \"https\" {\n\t\treturn \"\", fmt.Errorf(\"仅允许 http/https, 实际为 %q\", u.Scheme)\n\t}\n\tmethod := strings.ToUpper(strings.TrimSpace(t.HttpMethod))\n\tif method == \"\" {\n\t\tmethod = http.MethodGet\n\t}\n\tvar body io.Reader\n\tif t.HttpBody != \"\" {\n\t\tbody = strings.NewReader(t.HttpBody)\n\t}\n\treq, err := http.NewRequest(method, t.HttpUrl, body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"构造请求失败: %w\", err)\n\t}\n\tif len(t.HttpHeader) > 0 {\n\t\tvar hdr map[string]string\n\t\tif err := json.Unmarshal(t.HttpHeader, &hdr); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"http_header 必须是 JSON 对象: %w\", err)\n\t\t}\n\t\tfor k, v := range hdr {\n\t\t\treq.Header.Set(k, v)\n\t\t}\n\t}\n\n\tclient := newTimedTaskHTTPClient(t.HttpAllowPrivate, defaultHTTPTimeout)\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tvar uerr *url.Error\n\t\tif errors.As(err, &uerr) && uerr.Timeout() {\n\t\t\treturn \"\", errTaskTimeout\n\t\t}","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_timed_task_runner.go#L126-L162","documentation":"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.","triggerScenarios":"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.","commonSituations":"Typo in method field like 'GET ' with a trailing character or lowercase custom verbs containing spaces; corrupted http_method column data from an import.","solutions":["Fix t.HttpMethod to a valid HTTP verb (GET, POST, PUT, DELETE, PATCH... or empty for default GET)","Inspect the wrapped %w error for the precise NewRequest cause and correct the corresponding field","Validate/sanitize method input in the task-creation API"],"exampleFix":"// before\nHttpMethod: \"POST JSON\"\n// after\nHttpMethod: \"POST\"","handlingStrategy":"validation","validationCode":"method := strings.ToUpper(strings.TrimSpace(httpMethod))\nvalid := map[string]bool{\"GET\":true,\"POST\":true,\"PUT\":true,\"DELETE\":true,\"PATCH\":true,\"HEAD\":true,\"OPTIONS\":true}\nif method != \"\" && !valid[method] {\n    return fmt.Errorf(\"invalid HTTP method: %s\", method)\n}","typeGuard":"func isValidMethod(m string) bool {\n    switch strings.ToUpper(strings.TrimSpace(m)) {\n    case \"\", \"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"HEAD\", \"OPTIONS\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"if err := RunTask(t); err != nil {\n    if strings.Contains(err.Error(), \"构造请求失败\") {\n        log.Warnf(\"task %d failed request construction: %v\", t.ID, err)\n    }\n}","preventionTips":["Restrict http_method to a fixed set of verbs in the admin UI","Trim and uppercase method input before persisting","Log the wrapped underlying error to see NewRequest's exact complaint"],"tags":["http","request-construction","timed-task"],"backgroundTag":"invalid-http-request","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}