Skip to content

Commit 0049ce7

Browse files
committed
GH-2652: Make RabbitListenerErrorHandler aware of Channel
Fixes: #2652 Whenever a `MessageConversionException` occurs, the raw Spring message returned in `RabbitListenerErrorHandler#handleError` is null. Channel information is being stored inside of that raw message, therefore it is not possible to manually nack just failed message * Introduce a new `handleError(Message, Channel, Message<?>, ListenerExecutionFailedException)` contract to make a `Channel` access independent of the `Message<?>` result * Deprecate existing method with the plan to remove in the next version (see #2654)
1 parent d135246 commit 0049ce7

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/adapter/MessagingMessageListenerAdapter.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -182,10 +182,11 @@ private void handleException(org.springframework.amqp.core.Message amqpMessage,
182182
Message<?> messageWithChannel = null;
183183
if (message != null) {
184184
messageWithChannel = MessageBuilder.fromMessage(message)
185+
// TODO won't be necessary starting with version 3.2
185186
.setHeader(AmqpHeaders.CHANNEL, channel)
186187
.build();
187188
}
188-
Object errorResult = this.errorHandler.handleError(amqpMessage, messageWithChannel, e);
189+
Object errorResult = this.errorHandler.handleError(amqpMessage, channel, messageWithChannel, e);
189190
if (errorResult != null) {
190191
Object payload = message == null ? null : message.getPayload();
191192
InvocationResult invResult = payload == null

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/api/RabbitListenerErrorHandler.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2021 the original author or authors.
2+
* Copyright 2016-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020
import org.springframework.amqp.rabbit.support.ListenerExecutionFailedException;
2121
import org.springframework.lang.Nullable;
2222

23+
import com.rabbitmq.client.Channel;
2324
/**
2425
* An error handler which is called when a {code @RabbitListener} method
2526
* throws an exception. This is invoked higher up the stack than the
@@ -41,8 +42,31 @@ public interface RabbitListenerErrorHandler {
4142
* {@link ListenerExecutionFailedException}.
4243
* @return the return value to be sent to the sender.
4344
* @throws Exception an exception which may be the original or different.
45+
* @deprecated in favor of
46+
* {@link #handleError(Message, Channel, org.springframework.messaging.Message, ListenerExecutionFailedException)}
4447
*/
48+
@Deprecated(forRemoval = true, since = "3.1.3")
4549
Object handleError(Message amqpMessage, @Nullable org.springframework.messaging.Message<?> message,
4650
ListenerExecutionFailedException exception) throws Exception; // NOSONAR
4751

52+
/**
53+
* Handle the error. If an exception is not thrown, the return value is returned to
54+
* the sender using normal {@code replyTo/@SendTo} semantics.
55+
* @param amqpMessage the raw message received.
56+
* @param channel AMQP channel for manual acks.
57+
* @param message the converted spring-messaging message (if available).
58+
* @param exception the exception the listener threw, wrapped in a
59+
* {@link ListenerExecutionFailedException}.
60+
* @return the return value to be sent to the sender.
61+
* @throws Exception an exception which may be the original or different.
62+
* @since 3.1.3
63+
*/
64+
@SuppressWarnings("deprecation")
65+
default Object handleError(Message amqpMessage, Channel channel,
66+
@Nullable org.springframework.messaging.Message<?> message,
67+
ListenerExecutionFailedException exception) throws Exception { // NOSONAR
68+
69+
return handleError(amqpMessage, message, exception);
70+
}
71+
4872
}

0 commit comments

Comments
 (0)