From 1a03e937dcd1a9a0ab1fee6be0f458291a3315af Mon Sep 17 00:00:00 2001 From: Edward Amsden Date: Fri, 27 Mar 2026 15:49:51 -0500 Subject: [PATCH 1/2] Add getVersion failure regression test --- .../WorkflowFailureGetVersionTest.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 temporal-sdk/src/test/java/io/temporal/workflow/failure/WorkflowFailureGetVersionTest.java diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/failure/WorkflowFailureGetVersionTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/failure/WorkflowFailureGetVersionTest.java new file mode 100644 index 0000000000..d240c5d86f --- /dev/null +++ b/temporal-sdk/src/test/java/io/temporal/workflow/failure/WorkflowFailureGetVersionTest.java @@ -0,0 +1,81 @@ +package io.temporal.workflow.failure; + +import static io.temporal.testUtils.Eventually.assertEventually; + +import io.temporal.api.common.v1.WorkflowExecution; +import io.temporal.api.enums.v1.EventType; +import io.temporal.api.failure.v1.Failure; +import io.temporal.api.history.v1.HistoryEvent; +import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowException; +import io.temporal.client.WorkflowStub; +import io.temporal.testing.internal.SDKTestWorkflowRule; +import io.temporal.workflow.Workflow; +import io.temporal.workflow.shared.TestWorkflows.TestWorkflow1; +import java.time.Duration; +import java.util.List; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; + +public class WorkflowFailureGetVersionTest { + + @Rule public TestName testName = new TestName(); + + @Rule + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() + .setWorkflowTypes(TestWorkflowGetVersionAndException.class) + .build(); + + @Test + public void getVersionAndException() { + TestWorkflow1 workflow = testWorkflowRule.newWorkflowStubTimeoutOptions(TestWorkflow1.class); + WorkflowExecution execution = WorkflowClient.start(workflow::execute, testName.getMethodName()); + WorkflowStub workflowStub = WorkflowStub.fromTyped(workflow); + + try { + HistoryEvent workflowTaskFailed = + assertEventually( + Duration.ofSeconds(5), + () -> { + List failedEvents = + testWorkflowRule.getHistoryEvents( + execution.getWorkflowId(), EventType.EVENT_TYPE_WORKFLOW_TASK_FAILED); + Assert.assertFalse("No workflow task failure recorded", failedEvents.isEmpty()); + return failedEvents.get(0); + }); + + Failure failure = + getDeepestFailure(workflowTaskFailed.getWorkflowTaskFailedEventAttributes().getFailure()); + Assert.assertEquals("Any error", failure.getMessage()); + Assert.assertTrue(failure.hasApplicationFailureInfo()); + Assert.assertEquals( + RuntimeException.class.getName(), failure.getApplicationFailureInfo().getType()); + } finally { + try { + workflowStub.terminate("terminate test workflow"); + } catch (WorkflowException ignored) { + } + } + } + + private static Failure getDeepestFailure(Failure failure) { + while (failure.hasCause()) { + failure = failure.getCause(); + } + return failure; + } + + public static class TestWorkflowGetVersionAndException implements TestWorkflow1 { + + @Override + public String execute(String unused) { + String changeId = "change-id"; + Workflow.getVersion(changeId, Workflow.DEFAULT_VERSION, 1); + Workflow.getVersion(changeId, Workflow.DEFAULT_VERSION, 1); + throw new RuntimeException("Any error"); + } + } +} From d71f645e1f0c13756282750f060cb8bcca879bc6 Mon Sep 17 00:00:00 2001 From: Edward Amsden Date: Fri, 27 Mar 2026 16:07:23 -0500 Subject: [PATCH 2/2] Add SKIP_YIELD_ON_VERSION to WorkflowStateMachines.initialFlags, fixing exception masking after multiple `getVersion()` calls --- .../temporal/internal/statemachines/WorkflowStateMachines.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java b/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java index 2f2c716f24..1dd15baacc 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java @@ -52,7 +52,8 @@ enum HandleEventStatus { /** Initial set of SDK flags that will be set on all new workflow executions. */ @VisibleForTesting public static List initialFlags = - Collections.unmodifiableList(Arrays.asList(SdkFlag.SKIP_YIELD_ON_DEFAULT_VERSION)); + Collections.unmodifiableList( + Arrays.asList(SdkFlag.SKIP_YIELD_ON_DEFAULT_VERSION, SdkFlag.SKIP_YIELD_ON_VERSION)); /** * Keep track of the change versions that have been seen by the SDK. This is used to generate the