diff --git a/temporal-sdk/src/main/java/io/temporal/internal/nexus/NexusTaskHandlerImpl.java b/temporal-sdk/src/main/java/io/temporal/internal/nexus/NexusTaskHandlerImpl.java index 4d40183c27..c0a538da26 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/nexus/NexusTaskHandlerImpl.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/nexus/NexusTaskHandlerImpl.java @@ -200,6 +200,9 @@ private void convertKnownFailures(Throwable e) { } throw new HandlerException(HandlerException.ErrorType.BAD_REQUEST, failure); } + if (failure instanceof IllegalArgumentException) { + throw new HandlerException(HandlerException.ErrorType.BAD_REQUEST, failure); + } if (failure instanceof ApplicationFailure) { if (((ApplicationFailure) failure).isNonRetryable()) { throw new HandlerException( diff --git a/temporal-sdk/src/test/java/io/temporal/internal/nexus/NexusTaskHandlerImplTest.java b/temporal-sdk/src/test/java/io/temporal/internal/nexus/NexusTaskHandlerImplTest.java index 2ddfa7fda1..5f71fb158e 100644 --- a/temporal-sdk/src/test/java/io/temporal/internal/nexus/NexusTaskHandlerImplTest.java +++ b/temporal-sdk/src/test/java/io/temporal/internal/nexus/NexusTaskHandlerImplTest.java @@ -162,6 +162,34 @@ public void startTaskWithUndeserializableInput() throws TimeoutException { Assert.assertFalse(e.isRetryable()); } + @Test + public void startTaskHandlerMissingBothActivityTimeoutOptions() throws TimeoutException { + WorkflowClient client = mock(WorkflowClient.class); + NexusTaskHandlerImpl nexusTaskHandlerImpl = + new NexusTaskHandlerImpl( + client, NAMESPACE, TASK_QUEUE, dataConverter, new WorkerInterceptor[] {}); + nexusTaskHandlerImpl.registerNexusServiceImplementations( + new Object[] {new ThrowingIllegalArgumentServiceImpl()}); + nexusTaskHandlerImpl.start(); + + PollNexusTaskQueueResponse.Builder task = + PollNexusTaskQueueResponse.newBuilder() + .setRequest( + Request.newBuilder() + .setStartOperation( + StartOperationRequest.newBuilder() + .setOperation("operation") + .setService("TestNexusService1") + .setPayload(dataConverter.toPayload("input").get()) + .build())); + + NexusTaskHandler.Result result = + nexusTaskHandlerImpl.handle(new NexusTask(task, null, null), metricsScope); + HandlerException e = result.getHandlerException(); + Assert.assertNotNull(e); + Assert.assertEquals(HandlerException.ErrorType.BAD_REQUEST, e.getErrorType()); + } + @Test public void startAsyncSyncOperation() throws TimeoutException { WorkflowClient client = mock(WorkflowClient.class); @@ -405,6 +433,18 @@ public OperationHandler operation() { } } + @ServiceImpl(service = TestNexusServices.TestNexusService1.class) + public class ThrowingIllegalArgumentServiceImpl { + @OperationImpl + public OperationHandler operation() { + return OperationHandler.sync( + (ctx, details, input) -> { + throw new IllegalArgumentException( + "at least one of StartToCloseTimeout or ScheduleToCloseTimeout is required"); + }); + } + } + @ServiceImpl(service = TestNexusServices.TestNexusService1.class) public class TestNexusServiceImpl { @OperationImpl