From e24572c8d36980ce6e9346183bdaf73da9cf4608 Mon Sep 17 00:00:00 2001 From: wank125 <30768017+wank125@users.noreply.github.com> Date: Thu, 8 Oct 2026 06:59:42 +0800 Subject: [PATCH] [Fix-18677][master] Null-safe taskExecuteType in task finish logging and default it to BATCH on save Task definitions created via the workflow export/import round trip can carry taskExecuteType=null (the exported JSON has no taskExecuteType and the import path does not default it; the column has no default value either). When such a task finishes, WorkflowInstanceUtils#logTaskInstanceInDetail throws an NPE on the taskFinish path, the state event is retried a few times and then dropped, leaving the task instance stuck in RUNNING forever, the workflow instance never completing, and the master re-dispatching the shell repeatedly. - logTaskInstanceInDetail renders null taskExecuteType as N/A instead of throwing, so a logging helper can no longer crash the task finish chain - ProcessServiceImpl#saveTaskDefine defaults a missing taskExecuteType to BATCH, so task definitions saved from import (and any other caller) never persist null Verified on a 3.2.2 deployment: 48 imported task definitions with task_execute_type NULL deterministically reproduced the stuck state; fixing the data restored normal completion immediately. --- .../master/utils/WorkflowInstanceUtils.java | 6 +++++- .../utils/WorkflowInstanceUtilsTest.java | 21 +++++++++++++++++++ .../service/process/ProcessServiceImpl.java | 6 ++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/utils/WorkflowInstanceUtils.java b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/utils/WorkflowInstanceUtils.java index dbf89bba401c..1483a352226c 100644 --- a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/utils/WorkflowInstanceUtils.java +++ b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/utils/WorkflowInstanceUtils.java @@ -91,7 +91,11 @@ public String logTaskInstanceInDetail(TaskInstance taskInstance) { .append(Strings.repeat("*", horizontalLineLength)).append("\n") .append("Task Name: ").append(taskInstance.getName()).append("\n") .append("Workflow Instance Name: ").append(taskInstance.getWorkflowInstance().getName()).append("\n") - .append("Task Execute Type: ").append(taskInstance.getTaskExecuteType().getDesc()).append("\n") + .append("Task Execute Type: ") + .append(taskInstance.getTaskExecuteType() == null + ? "N/A" + : taskInstance.getTaskExecuteType().getDesc()) + .append("\n") .append("Execute State: ").append(taskInstance.getState().getDesc()).append("\n") .append("Host: ").append(taskInstance.getHost()).append("\n") .append("Task Type: ").append(taskInstance.getTaskType()).append("\n") diff --git a/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/utils/WorkflowInstanceUtilsTest.java b/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/utils/WorkflowInstanceUtilsTest.java index 603fe50eb285..6d11a1882403 100644 --- a/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/utils/WorkflowInstanceUtilsTest.java +++ b/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/utils/WorkflowInstanceUtilsTest.java @@ -113,4 +113,25 @@ public void testLogTaskInstanceInDetails() { + "Start Time: 2023-08-01\n" + "End Time: 2023-08-01\n", WorkflowInstanceUtils.logTaskInstanceInDetail(taskInstance)); } + + @Test + public void testLogTaskInstanceInDetailWithNullTaskExecuteType() { + // taskExecuteType is null when the task definition was created via workflow + // export/import; the log helper must not throw NPE on the task finish path + WorkflowInstance workflowInstance = new WorkflowInstance(); + workflowInstance.setName("test_process"); + workflowInstance.setTenantCode("default"); + + TaskInstance taskInstance = new TaskInstance(); + taskInstance.setName("test_task"); + taskInstance.setWorkflowInstance(workflowInstance); + taskInstance.setState(TaskExecutionStatus.SUCCESS); + taskInstance.setTaskExecuteType(null); + taskInstance.setHost("127.0.0.1"); + taskInstance.setTaskType("SHELL"); + taskInstance.setTaskInstancePriority(Priority.MEDIUM); + + String detail = WorkflowInstanceUtils.logTaskInstanceInDetail(taskInstance); + Assertions.assertTrue(detail.contains("Task Execute Type: N/A")); + } } diff --git a/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessServiceImpl.java b/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessServiceImpl.java index 1469a909b23f..d450f9285897 100644 --- a/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessServiceImpl.java +++ b/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessServiceImpl.java @@ -24,6 +24,7 @@ import org.apache.dolphinscheduler.common.enums.AuthorizationType; import org.apache.dolphinscheduler.common.enums.Flag; import org.apache.dolphinscheduler.common.enums.ReleaseState; +import org.apache.dolphinscheduler.common.enums.TaskExecuteType; import org.apache.dolphinscheduler.common.enums.TimeoutFlag; import org.apache.dolphinscheduler.common.enums.WorkflowExecutionStatus; import org.apache.dolphinscheduler.common.graph.DAG; @@ -438,6 +439,11 @@ public int saveTaskDefine(User operator, long projectCode, List