{"record":{"id":"d174ba08525570e3","repo":"flipped-aurora/gin-vue-admin","slug":"error-d174ba","errorCode":null,"errorMessage":"任务执行超时","messagePattern":"任务执行超时","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/service/system/sys_timed_task_runner.go","lineNumber":37,"sourceCode":"\t\"github.com/flipped-aurora/gin-vue-admin/server/utils/logger\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/utils/sse\"\n)\n\n// 超时用 var 而非 const: 单测需收窄\nvar (\n\tdefaultMethodTimeout = 5 * time.Minute\n\tdefaultHTTPTimeout   = 30 * time.Second\n)\n\nconst (\n\tmaxHTTPRespBytes = 1 << 20 // HTTP 响应体读取上限 1MB\n\tmaxLogTextLen    = 4000    // error/output 落库截断长度\n\talertAuthorityID = 888     // 失败告警接收角色\n\talertEventName   = \"timedTask:alert\"\n)\n\n// errTaskTimeout 超时哨兵: Runner 据此把状态记为 timeout 而非 fail\nvar errTaskTimeout = errors.New(\"任务执行超时\")\n\nfunc truncateText(s string, n int) string {\n\tif len(s) <= n {\n\t\treturn s\n\t}\n\treturn s[:n] + \"...(截断)\"\n}\n\n// RunTask 统一执行入口(自动调度与手动触发共用):\n// panic 兜底、起止/耗时/状态/错误落 sys_timed_task_logs、失败经 SSE 告警。\n// 阻塞执行; 调度器回调与手动触发均应在独立 goroutine 中调用。\nfunc (s *TimedTaskService) RunTask(t system.SysTimedTask, trigger string) {\n\tstarted := time.Now()\n\tvar output string\n\tvar runErr error\n\tswitch t.ExecutorType {\n\tcase system.TimedTaskExecutorMethod:\n\t\toutput, runErr = s.runMethod(t)","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_timed_task_runner.go#L19-L55","documentation":"errTaskTimeout is the sentinel error returned by RunTask/runMethod/runHTTP when a timed task exceeds its execution deadline. The runner recognizes it via errors.Is and records the task run's status as \"timeout\" rather than \"fail\", enabling different alerting/metrics.","triggerScenarios":"A method-executor task whose registered function blocks past the configured timeout (deadlocks, slow queries); an HTTP-executor task calling a slow or hanging endpoint that doesn't respond within the deadline.","commonSituations":"HTTP targets stuck waiting on downstream services without their own timeout; DB queries that scan large tables; method tasks doing synchronous network I/O; timeout configured too low for legitimately slow jobs.","solutions":["Increase the task's timeout configuration if the workload legitimately needs longer.","Add/raise timeouts inside the task's own HTTP client or DB queries so they fail fast and meaningfully.","Optimize the slow operation (indexes, pagination, async processing).","Check task run logs for partial output to identify where the task hangs."],"exampleFix":"// before\nclient := &http.Client{} // no timeout inside task; runner kills at deadline\n\n// after\nclient := &http.Client{Timeout: 20 * time.Second} // well under task timeout","handlingStrategy":"try-catch","validationCode":"if task.TimeoutSeconds > 0 && estimatedDuration > time.Duration(task.TimeoutSeconds)*time.Second {\n    log.Warnf(\"task %s may exceed its %ds timeout\", task.Name, task.TimeoutSeconds)\n}","typeGuard":null,"tryCatchPattern":"if err := runner.RunTask(ctx, task); err != nil {\n    if errors.Is(err, errTaskTimeout) {\n        log.Warnf(\"task %s timed out; consider raising its timeout or optimizing the job\", task.Name)\n        return\n    }\n    log.Errorf(\"task %s failed: %v\", task.Name, err)\n}","preventionTips":["Set timeouts on HTTP clients and DB queries inside task bodies","Size the task timeout to the job's realistic worst case","Alert on repeated timeout-status runs via the built-in alert event","Profile slow tasks instead of endlessly raising the deadline"],"tags":["timeout","scheduled-task","go","http"],"backgroundTag":"task-execution-timeout","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}