diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java index ee81fd5f1..68b6c7432 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptor.java @@ -192,13 +192,15 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter Message retrievedMessage, MessageHeaderAccessor additionalHeaders) { MessageHeaderAccessor headers = MessageHeaderAccessor .getMutableAccessor(originalMessage); - if (originalMessage.getPayload() instanceof MessagingException) { + if (originalMessage instanceof ErrorMessage) { + ErrorMessage errorMessage = (ErrorMessage) originalMessage; headers.copyHeaders(MessageHeaderPropagation.propagationHeaders( additionalHeaders.getMessageHeaders(), this.tracing.propagation().keys())); - return new ErrorMessage((MessagingException) originalMessage.getPayload(), + return new ErrorMessage(errorMessage.getPayload(), isWebSockets(headers) ? headers.getMessageHeaders() - : new MessageHeaders(headers.getMessageHeaders())); + : new MessageHeaders(headers.getMessageHeaders()), + errorMessage.getOriginalMessage()); } headers.copyHeaders(additionalHeaders.getMessageHeaders()); return new GenericMessage<>(retrievedMessage.getPayload(), @@ -268,6 +270,11 @@ public final class TracingChannelInterceptor extends ChannelInterceptorAdapter log.debug("Created a new span in post receive " + span); } headers.setImmutable(); + if (message instanceof ErrorMessage) { + ErrorMessage errorMessage = (ErrorMessage) message; + return new ErrorMessage(errorMessage.getPayload(), headers.getMessageHeaders(), + errorMessage.getOriginalMessage()); + } return new GenericMessage<>(message.getPayload(), headers.getMessageHeaders()); } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java index a583d74c8..af6637ced 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java @@ -283,6 +283,28 @@ public class TracingChannelInterceptorTest { .isSameAs(errorsReplyChannel); } + @Test + public void errorMessageOriginalMessageRetained() { + this.channel.addInterceptor(this.interceptor); + Message originalMessage = MessageBuilder.withPayload("Hello") + .setHeader("header", "value").build(); + Message failedMessage = MessageBuilder.fromMessage(originalMessage) + .removeHeader("header").build(); + this.channel.send(new ErrorMessage(new MessagingException(failedMessage), + originalMessage.getHeaders(), originalMessage)); + + this.message = this.channel.receive(); + + assertThat(this.message).isNotNull(); + assertThat(this.message) + .isInstanceOfSatisfying(ErrorMessage.class, errorMessage -> { + assertThat(errorMessage.getOriginalMessage()) + .isSameAs(originalMessage); + assertThat(errorMessage.getHeaders().get("header")) + .isEqualTo("value"); + }); + } + ChannelInterceptor producerSideOnly(ChannelInterceptor delegate) { return new ChannelInterceptorAdapter() { @Override