Search code examples
rabbitmqspring-amqpspring-rabbit

Throwing exceptions in RabbitMQ listener interceptors (advices)


I've a listener like the following :

@RabbitListener(queues = "${myQueue}")
public void receiveMessages(Message message) {
   doTheBusinessLogic(message)
}

I understand from here What is the ServletFilter equalent of a RabbitMq Listener?

that we can execute some logic before getting inside the listener (an 'interceptor'), using Advice :

see the following code :

 @Bean(name = "rabbitListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        factory.setAdviceChain(new MDCAdvice());
        return factory;
    }

So my question is : if i throw a runtime exception from inside an advice (like this MDCAdvice) is it like i throw it from inside the listener method ?

 public static class MDCAdvice implements MethodInterceptor {

        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            // pre process
            if (throwBefore) throw new RuntimeException("before")
            try {
                return invocation.proceed();
            }
            finally {
             // post process
            throw new RuntimeException("after")

            }
        }

    }

I mean : is a NACK returned to rabbitmq ? Is the transaction rolled back if the listener is transactional ?

In general, is totally equivalent to throw it inside the doTheBusinessLogic(message) above ?

Thank you for your help


Solution

  • Yes; any exception thrown in the advice(s) will cause the same behavior as if the exception was thrown in the listener itself.

    For example, if you want to discard a message, throw a AmqpRejectAndDontRequeueException.

    You can achieve the same by using a MessagePostProcessor (in the afterReceivePostProcessors and return null.