I did read this reference: https://www.rabbitmq.com/dlx.html, however it doesn\'t resolve my doubts, namely:
In case of accepting message there is no problem - spring-
RabbitMQ knows nothing about the exceptions.
When the container catches an exception it calls channel.basicReject(deliveryTag, requeue)
.
If requeue is true, the message is requeued.
By default, for any exception other than those mentioned here
o.s.amqp...MessageConversionException
o.s.messaging...MessageConversionException
o.s.messaging...MethodArgumentNotValidException
o.s.messaging...MethodArgumentTypeMismatchException
java.lang.NoSuchMethodException
java.lang.ClassCastException
requeue
is set to true, so the message is requeued.
For those exceptions, the delivery is considered fatal and the message is NOT requeued, it will go to a DLX/DLQ if one is configured.
The container has a flag defaultRequeueRejected
which is true by default; if you set it to false
; no exceptions will be requeued.
For application-level exceptions, generally, messages will be requeued. To dynamically reject (and not requeue) a message, make sure there is an AmqpRejectAndDontRequeueException
in the cause chain. This instructs the container to not requeue the message, and it will go to the DLX/DLQ (if configured). This behavior is enabled by the defaultRequeueRejected
flag mentioned above.
This is all explained in the documentation and, as I have discussed in other answers to you, you can change this behavior by using a custom error handler; that, too, is explained in the documentation.
It is not possible to send some exceptions to the DLX/DLQ and not others; rabbit only has a binary option, requeue or don't requeue and, for the latter, if a DLX/DLQ is configured all such rejected messages go to the DLX/DLQ.
Spring AMQP provides one more exception, ImmediateAcknowledgeAmqpException
. If your listener throws this exception, the message will be ack'd as if it was processed successfully (channel.basicAck()
). That is the only technique provided by the container, to discard a bad message without sending it to the DLX/DLQ.
Of course, your application can drop such messsages itself.
If you want to DLX/DLQ all business exceptions but drop conversion exceptions, throw AmqpRejectAndDontRequeueException
(or set defaultRequeueRejected
to false), and throw ImmediateAcknowledgeAmqpException
from your converter.