From 3b60e456791bca6be74b2e093c2168c156fab1a4 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Thu, 22 Oct 2020 11:41:34 -0400 Subject: [PATCH] Gateway: Propagate Error to the errorChannel See SO for more info: https://stackoverflow.com/questions/64456946/handle-exceptions-errors-other-than-messagingexception-ie-other-error-excepti In the versions before `5.2.x` the `Error` was wrapped to the `MessagingException` in the `AbstractRequestHandlerAdvice` and this one was handled properly on the gateway level with its `errorChannel` configured * Fix `MessagingGatewaySupport` to catch all the `Throwable` and try to send them as `ErrorMessage` to the `errorChannel`. Otherwise unwrap returned `MessagingException` and re-throw an `Error` as is to keep the current behavior for non-handled exceptions * Do not wrap `Error` into a `MessagingException` and re-throw as is if there is no `errorChannel` **Cherry-pick to 5.3.x & 5.2.x** --- .../gateway/MessagingGatewaySupport.java | 5 ++++- .../integration/gateway/AsyncGatewayTests.java | 17 +++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java index 76d94dd29d..df47627815 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java @@ -526,7 +526,7 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint throwMessageTimeoutException(object, "No reply received within timeout"); } } - catch (Exception ex) { + catch (Throwable ex) { // NOSONAR (catch throwable) if (logger.isDebugEnabled()) { logger.debug("failure occurred in gateway sendAndReceive: " + ex.getMessage()); } @@ -561,6 +561,9 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint : errorFlowReply; } } + else if (error instanceof Error) { + throw (Error) error; + } else { Throwable errorToReThrow = error; if (error instanceof MessagingException && diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/AsyncGatewayTests.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/AsyncGatewayTests.java index 993549c47a..800e9354b0 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/AsyncGatewayTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/AsyncGatewayTests.java @@ -17,7 +17,7 @@ package org.springframework.integration.gateway; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.mock; import java.time.Duration; @@ -27,7 +27,7 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.integration.annotation.Gateway; @@ -88,13 +88,10 @@ public class AsyncGatewayTests { proxyFactory.afterPropertiesSet(); TestEchoService service = (TestEchoService) proxyFactory.getObject(); Future> f = service.returnMessage("foo"); - try { - f.get(10000, TimeUnit.MILLISECONDS); - fail("Expected Exception"); - } - catch (ExecutionException e) { - assertThat(e.getCause()).isEqualTo(error); - } + + assertThatExceptionOfType(ExecutionException.class) + .isThrownBy(() -> f.get(10000, TimeUnit.MILLISECONDS)) + .withCause(error); } @Test @@ -134,7 +131,7 @@ public class AsyncGatewayTests { } @Test - public void customFutureReturned() throws Exception { + public void customFutureReturned() { QueueChannel requestChannel = new QueueChannel(); addThreadEnricher(requestChannel); startResponder(requestChannel);