Closed Quinn-With-Two-Ns closed 2 months ago
Test server treats internal errors from nexus operations as retryable
Test server treats internal errors from nexus operations as non-retryable
package io.temporal.workflow.nexus; import static org.junit.Assume.assumeTrue; import io.nexusrpc.handler.OperationHandler; import io.nexusrpc.handler.OperationImpl; import io.nexusrpc.handler.ServiceImpl; import io.temporal.client.WorkflowFailedException; import io.temporal.failure.NexusOperationFailure; import io.temporal.failure.TimeoutFailure; import io.temporal.testing.internal.SDKTestWorkflowRule; import io.temporal.workflow.*; import io.temporal.workflow.shared.TestNexusServices; import io.temporal.workflow.shared.TestWorkflows; import java.time.Duration; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; public class SyncOperationTimeoutTest extends BaseNexusTest { @Rule public SDKTestWorkflowRule testWorkflowRule = SDKTestWorkflowRule.newBuilder() .setWorkflowTypes(TestNexus.class) .setNexusServiceImplementation(new TestNexusServiceImpl()) .build(); @Override protected SDKTestWorkflowRule getTestWorkflowRule() { return testWorkflowRule; } @Test public void typedOperationTimeout() { TestWorkflows.TestWorkflow1 workflowStub = testWorkflowRule.newWorkflowStubTimeoutOptions(TestWorkflows.TestWorkflow1.class); WorkflowFailedException exception = Assert.assertThrows(WorkflowFailedException.class, () -> workflowStub.execute("")); Assert.assertTrue(exception.getCause() instanceof NexusOperationFailure); NexusOperationFailure nexusFailure = (NexusOperationFailure) exception.getCause(); Assert.assertTrue(nexusFailure.getCause() instanceof TimeoutFailure); TimeoutFailure timeoutFailure = (TimeoutFailure) nexusFailure.getCause(); Assert.assertEquals("operation timed out", timeoutFailure.getOriginalMessage()); } public static class TestNexus implements TestWorkflows.TestWorkflow1 { @Override public String execute(String input) { NexusOperationOptions options = NexusOperationOptions.newBuilder() .setScheduleToCloseTimeout(Duration.ofSeconds(1)) .build(); NexusServiceOptions serviceOptions = NexusServiceOptions.newBuilder() .setEndpoint(getEndpointName()) .setOperationOptions(options) .build(); // Try to call a synchronous operation in a blocking way TestNexusServices.TestNexusService1 serviceStub = Workflow.newNexusServiceStub(TestNexusServices.TestNexusService1.class, serviceOptions); return serviceStub.operation("test timeout"); } } @ServiceImpl(service = TestNexusServices.TestNexusService1.class) public class TestNexusServiceImpl { @OperationImpl public OperationHandler<String, String> operation() { // Implemented inline return OperationHandler.sync( (ctx, details, name) -> { throw new RuntimeException("failed to call operation"); }); } } }
Expected Behavior
Test server treats internal errors from nexus operations as retryable
Actual Behavior
Test server treats internal errors from nexus operations as non-retryable
Steps to Reproduce the Problem