From d1188da3a2c4b76e1cad05892619107f0103694d Mon Sep 17 00:00:00 2001 From: Matt Nichols Date: Tue, 30 May 2023 14:45:55 -0600 Subject: [PATCH] feat: clean up fault-tolerant executor exception handling This removes the extra throw of ConnectException on an unknown exception. By allowing Exception to be thrown in the interface, we can allow any non-R4J exception to be handled up the stack. --- .../Resilience4jFaultTolerantExecutor.java | 13 +----------- ...silience4jFaultTolerantExecutorTest.groovy | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/fault-tolerant-executor-resilience4j/src/main/java/com/mx/path/service/facility/fault_tolerant_executor/resilience4j/Resilience4jFaultTolerantExecutor.java b/fault-tolerant-executor-resilience4j/src/main/java/com/mx/path/service/facility/fault_tolerant_executor/resilience4j/Resilience4jFaultTolerantExecutor.java index 94f78e9..e6ee0fd 100644 --- a/fault-tolerant-executor-resilience4j/src/main/java/com/mx/path/service/facility/fault_tolerant_executor/resilience4j/Resilience4jFaultTolerantExecutor.java +++ b/fault-tolerant-executor-resilience4j/src/main/java/com/mx/path/service/facility/fault_tolerant_executor/resilience4j/Resilience4jFaultTolerantExecutor.java @@ -7,13 +7,9 @@ import lombok.AccessLevel; import lombok.Setter; -import com.mx.path.core.common.accessor.PathResponseStatus; import com.mx.path.core.common.configuration.Configuration; -import com.mx.path.core.common.connect.ConnectException; import com.mx.path.core.common.connect.ServiceUnavailableException; import com.mx.path.core.common.connect.TooManyRequestsException; -import com.mx.path.core.common.exception.PathRequestException; -import com.mx.path.core.common.exception.PathSystemException; import com.mx.path.core.common.process.FaultTolerantExecutor; import com.mx.path.core.common.process.FaultTolerantTask; import com.mx.path.service.facility.fault_tolerant_executor.resilience4j.configuration.Configurations; @@ -36,7 +32,7 @@ public Resilience4jFaultTolerantExecutor(@Configuration Configurations configura @SuppressWarnings("PMD.CyclomaticComplexity") @Override - public void submit(String scope, FaultTolerantTask task) { + public void submit(String scope, FaultTolerantTask task) throws Exception { try { executeDecoratorStack(scope, task); } catch (BulkheadFullException e) { @@ -51,13 +47,6 @@ public void submit(String scope, FaultTolerantTask task) { throw new com.mx.path.core.common.connect.TimeoutException( "Resilience4j triggered a timeout.", e); - } catch (PathRequestException | PathSystemException e) { - throw e; // rethrow Path exceptions - } catch (Exception e) { - throw new ConnectException( - "An unknown error occurred", - PathResponseStatus.INTERNAL_ERROR, - e); } } diff --git a/fault-tolerant-executor-resilience4j/src/test/groovy/com/mx/path/service/facility/fault_tolerant_executor/resilience4j/Resilience4jFaultTolerantExecutorTest.groovy b/fault-tolerant-executor-resilience4j/src/test/groovy/com/mx/path/service/facility/fault_tolerant_executor/resilience4j/Resilience4jFaultTolerantExecutorTest.groovy index 2a392c9..9b39f5d 100644 --- a/fault-tolerant-executor-resilience4j/src/test/groovy/com/mx/path/service/facility/fault_tolerant_executor/resilience4j/Resilience4jFaultTolerantExecutorTest.groovy +++ b/fault-tolerant-executor-resilience4j/src/test/groovy/com/mx/path/service/facility/fault_tolerant_executor/resilience4j/Resilience4jFaultTolerantExecutorTest.groovy @@ -6,6 +6,7 @@ import java.time.Duration import java.util.concurrent.TimeoutException import com.mx.path.core.common.accessor.PathResponseStatus +import com.mx.path.core.common.accessor.UpstreamSystemMaintenance import com.mx.path.core.common.connect.ConnectException import com.mx.path.core.common.connect.ServiceUnavailableException import com.mx.path.core.common.connect.TooManyRequestsException @@ -39,16 +40,19 @@ class Resilience4jFaultTolerantExecutorTest extends Specification { subject.submit("DEFAULT", { config -> }) then: - def exception = thrown(ConnectException) - exception.status == failureStatus - exception.cause == originalException + def exception = thrown(expectedType) + failureStatus == null ? !exception.hasProperty("status") : exception.status == failureStatus + !wrapsOriginalException || exception.cause == originalException + wrapsOriginalException || exception.cause == null where: - originalException || failureStatus - mock(BulkheadFullException) || PathResponseStatus.UPSTREAM_SERVICE_UNAVAILABLE - mock(CallNotPermittedException) || PathResponseStatus.UPSTREAM_SERVICE_UNAVAILABLE - new TimeoutException() || PathResponseStatus.UPSTREAM_SERVICE_UNAVAILABLE - new RuntimeException() || PathResponseStatus.INTERNAL_ERROR + originalException || wrapsOriginalException || expectedType || failureStatus + mock(BulkheadFullException) || true || TooManyRequestsException || PathResponseStatus.UPSTREAM_SERVICE_UNAVAILABLE + mock(CallNotPermittedException) || true || ServiceUnavailableException || PathResponseStatus.UPSTREAM_SERVICE_UNAVAILABLE + new TimeoutException() || true || com.mx.path.core.common.connect.TimeoutException || PathResponseStatus.UPSTREAM_SERVICE_UNAVAILABLE + new UpstreamSystemMaintenance("upstream is being maintained") || false || UpstreamSystemMaintenance || PathResponseStatus.UPSTREAM_SERVICE_UNAVAILABLE + new RuntimeException() || false || RuntimeException || null + new NullPointerException() || false || NullPointerException || null } def "runs a submitted task"() {