diff --git a/core/common/lib/state-machine-lib/src/main/java/org/eclipse/edc/statemachine/retry/StatusResultRetryProcess.java b/core/common/lib/state-machine-lib/src/main/java/org/eclipse/edc/statemachine/retry/StatusResultRetryProcess.java index a0782d4a592..41661203b44 100644 --- a/core/common/lib/state-machine-lib/src/main/java/org/eclipse/edc/statemachine/retry/StatusResultRetryProcess.java +++ b/core/common/lib/state-machine-lib/src/main/java/org/eclipse/edc/statemachine/retry/StatusResultRetryProcess.java @@ -24,6 +24,7 @@ import java.util.function.Supplier; import static java.lang.String.format; +import static org.eclipse.edc.spi.response.ResponseStatus.FATAL_ERROR; /** * Provides retry capabilities to a synchronous process that returns a {@link StatusResult} object @@ -45,7 +46,13 @@ public StatusResultRetryProcess(E entity, Supplier> process, Mon @Override boolean process(E entity, String description) { monitor.debug(format("%s: ID %s. %s", entity.getClass().getSimpleName(), entity.getId(), description)); - var result = process.get(); + + StatusResult result; + try { + result = process.get(); + } catch (Exception e) { + result = StatusResult.failure(FATAL_ERROR, "Unexpected exception thrown %s: %s".formatted(e, e.getMessage())); + } handleResult(entity, description, result); diff --git a/core/common/lib/state-machine-lib/src/test/java/org/eclipse/edc/statemachine/retry/StatusResultRetryProcessTest.java b/core/common/lib/state-machine-lib/src/test/java/org/eclipse/edc/statemachine/retry/StatusResultRetryProcessTest.java index 0153ce6c039..ae9758ecba8 100644 --- a/core/common/lib/state-machine-lib/src/test/java/org/eclipse/edc/statemachine/retry/StatusResultRetryProcessTest.java +++ b/core/common/lib/state-machine-lib/src/test/java/org/eclipse/edc/statemachine/retry/StatusResultRetryProcessTest.java @@ -14,6 +14,7 @@ package org.eclipse.edc.statemachine.retry; +import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.response.ResponseFailure; import org.eclipse.edc.spi.response.StatusResult; @@ -29,8 +30,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.spi.response.ResponseStatus.ERROR_RETRY; import static org.eclipse.edc.spi.response.ResponseStatus.FATAL_ERROR; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; class StatusResultRetryProcessTest { @@ -93,4 +97,19 @@ void shouldExecuteOnRetry_whenFailureAndRetriesHaveNotBeenExhausted() { verify(onFailure).accept(entity, statusResult.getFailure()); } + + + @Test + void shouldCallFatalError_whenExceptionIsThrown() { + when(process.get()).thenThrow(new EdcException("code throws an exception")); + var entity = TestEntity.Builder.newInstance().id(UUID.randomUUID().toString()).clock(clock).build(); + var retryProcess = new StatusResultRetryProcess<>(entity, process, mock(Monitor.class), clock, configuration); + + var result = retryProcess.onSuccess(onSuccess).onFatalError(onFatalError).execute("any"); + + assertThat(result).isTrue(); + verify(process).get(); + verify(onFatalError).accept(same(entity), any()); + verifyNoInteractions(onSuccess); + } }