2

I am currently working on a project involves consuming messages from RabbitMQ brocker. However, I am still new to Spring Integration, AMQP and RabbitMQ. I have an issue with consuming malformed messages formats. When my consumer receives a malformed message it returns it back the queue then RabbitMQ sends it back which creates an endless cycle. In Spring Integration documentation there are some configuration that can be implemented to that this kind of message are no returned back to the queue.

However I could not understand how to implement that. What I want is to be able to configure some kind of bean that has a format like

class ExceptionHandler {

   public void handle(Throwable e ) { 

     Logger.log("Some log ... we don't give a Sh** ... ") ; 

   } 

}

I've checked section 3.9 Exception Handling and 3.15.3 Message Listeners and the Asynchronous Case but unfortunately I could not understand anything.

So, if you have an example code or a link to one send it I will be greateful.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
Adelin
  • 18,144
  • 26
  • 115
  • 175

3 Answers3

1

After a lot of try-fails attempts I was able to handle the error. However I am struggling with harboring the exception log now. I don't understand why this is implemented this way. I was able to handle the log issue too. It turns that there is another way to say that you don't want to return the message back it is with acknowledge-mode="NONE" attribute. Checkout 10.2 Inbound Channel Adapter section.This way you don't even need to throw that ugly exception.

< bean id="handler" class="MessagesErrorHandler"/>
    < int-amqp:inbound-channel-adapter
            error-handler="handler"
            id="idActivityAdapter"
            channel="channelName"
            queue-names="activityQueue"
            />




import org.springframework.util.ErrorHandler;
import org.springframework.amqp.AmqpRejectAndDontRequeueException;

public class MessagesErrorHandler implements ErrorHandler {


    @Override
    public void handleError(Throwable throwable) {
        System.out.println("YESSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS ERROR IS HANDLED !!!!");
        throw new AmqpRejectAndDontRequeueException(throwable);// this very important
        //so that message don't go back to the queue. 
    }
}
Adelin
  • 18,144
  • 26
  • 115
  • 175
1

Yes, that's is one of the correct solution - to throw AmqpRejectAndDontRequeueException, when you decide that the message should not be requeued.

There is also defaultRequeueRejected on the SimpleMessageListenerContainer, which is true by default.

You maybe should to take a look to the DLX/DLQ solution to not lose those malformed messages.

Please, share the StackTrace which bothers you.

There is such a code in the SimpleMessageListenerContainer:

catch (AmqpRejectAndDontRequeueException rejectEx) {
                    /*
                     *  These will normally be wrapped by an LEFE if thrown by the
                     *  listener, but we will also honor it if thrown by an
                     *  error handler.
                     */
                }
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
0

The AmqpRejectAndDontRequeueException is a signal to the container to reject and not requeue the message; by default, it requeues any exception.

Alternatively, you can manually wire up a SimpleMessageListenerContainer bean; set defaultRequeueRejected to false and add it to the adapter using the container attribute. Then, all exceptions will cause messages to be rejected and not requeued.

Also, instead of an error-handler, you can use an error-channel and throw the AmqpRejectAndDontRequeueException from the error flow.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179