{"record":{"id":"88856f9f24d39094","repo":"flipped-aurora/gin-vue-admin","slug":"httpurl-http-https","errorCode":null,"errorMessage":"httpUrl 必须是合法的 http/https 地址","messagePattern":"httpUrl 必须是合法的 http/https 地址","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_timed_task.go","lineNumber":63,"sourceCode":"func (s *TimedTaskService) validateTask(t *system.SysTimedTask) error {\n\tif t.Name == \"\" {\n\t\treturn errors.New(\"任务名不能为空\")\n\t}\n\tif err := s.ValidateSpec(t.Spec, t.WithSeconds); err != nil {\n\t\treturn err\n\t}\n\tswitch t.ExecutorType {\n\tcase system.TimedTaskExecutorMethod:\n\t\tif _, ok := task.Get(t.MethodName); !ok {\n\t\t\treturn fmt.Errorf(\"方法 %s 未注册\", t.MethodName)\n\t\t}\n\t\tif len(t.Params) > 0 && !json.Valid(t.Params) {\n\t\t\treturn errors.New(\"params 必须是合法 JSON\")\n\t\t}\n\tcase system.TimedTaskExecutorHTTP:\n\t\tu, err := url.Parse(t.HttpUrl)\n\t\tif err != nil || (u.Scheme != \"http\" && u.Scheme != \"https\") || u.Host == \"\" {\n\t\t\treturn errors.New(\"httpUrl 必须是合法的 http/https 地址\")\n\t\t}\n\t\tif len(t.HttpHeader) > 0 {\n\t\t\tvar hdr map[string]string\n\t\t\tif err := json.Unmarshal(t.HttpHeader, &hdr); err != nil {\n\t\t\t\treturn errors.New(`httpHeader 必须是 {\"Key\":\"Value\"} 形式的 JSON 对象`)\n\t\t\t}\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"executorType 必须为 %s 或 %s\", system.TimedTaskExecutorMethod, system.TimedTaskExecutorHTTP)\n\t}\n\treturn nil\n}\n\n// checkNameUnique 软删除下不建 DB 唯一索引, 由服务层保证活跃行内唯一\nfunc (s *TimedTaskService) checkNameUnique(ctx context.Context, name string, excludeID uint) error {\n\tvar count int64\n\tdb := global.GVA_DB.WithContext(ctx).Model(&system.SysTimedTask{}).Where(\"name = ?\", name)\n\tif excludeID > 0 {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_timed_task.go#L45-L81","documentation":"validateTask throws \"httpUrl 必须是合法的 http/https 地址\" for HTTP-executor tasks when url.Parse fails, the scheme is not http/https, or the host is empty. This ensures the scheduler only dispatches to well-formed web endpoints.","triggerScenarios":"Creating/updating a task with ExecutorType=TimedTaskExecutorHTTP and HttpUrl like \"example.com/api\" (no scheme), \"ftp://host\", \"http://\" (empty host), or a string with spaces/illegal characters that makes url.Parse error.","commonSituations":"Users omitting the http:// prefix; internal URLs with typos; URLs pasted with surrounding whitespace; environment config where a base URL variable is empty so the URL becomes \"/path\" only.","solutions":["Include an explicit http:// or https:// scheme and a host in HttpUrl.","Trim whitespace from the URL before submitting.","Pre-validate with url.Parse in the client and check u.Scheme and u.Host.","Confirm the correct executor type: if you meant a registered method, use TimedTaskExecutorMethod instead."],"exampleFix":"// before\nHttpUrl: \"api.internal.local/ping\"\n\n// after\nHttpUrl: \"http://api.internal.local/ping\"","handlingStrategy":"validation","validationCode":"u, err := url.Parse(strings.TrimSpace(task.HttpUrl))\nif err != nil || (u.Scheme != \"http\" && u.Scheme != \"https\") || u.Host == \"\" {\n    return errors.New(\"httpUrl must be an absolute http/https URL\")\n}","typeGuard":"func validHTTPUrl(s string) bool {\n    u, err := url.Parse(strings.TrimSpace(s))\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","tryCatchPattern":"if err := svc.CreateTimedTask(ctx, task); err != nil {\n    if strings.Contains(err.Error(), \"httpUrl 必须是合法\") {\n        http.Error(w, \"provide an absolute http(s) URL with host\", http.StatusBadRequest)\n        return\n    }\n    http.Error(w, err.Error(), http.StatusInternalServerError)\n}","preventionTips":["Always include the scheme in stored URLs","Trim whitespace before validation","Prefer https for external endpoints","Pick the method executor when the target isn't a web endpoint"],"tags":["validation","url","http","go"],"backgroundTag":"invalid-url-format","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}