I have a consumer (RabbitListner) in RPC mode and I would like to know if it is possible to throw exception that can be treated by the publisher.
To make more clear my explication the case is as follow :
I try with the AmqpRejectAndDontRequeueException, but my publisher do not receive the exception, but just a response which is empty.
Is it possible to be done or may be it is not a good practice to implement like that ?
EDIT 1 :
After the @GaryRussel response here is the resolution of my question:
For the RabbitListner I create an error handler :
@Configuration
public class RabbitErrorHandler implements RabbitListenerErrorHandler {
@Override public Object handleError(Message message, org.springframework.messaging.Message<?> message1, ListenerExecutionFailedException e) {
throw e;
}
}
Define the bean into a configuration file :
@Configuration public class RabbitConfig extends RabbitConfiguration {
@Bean
public RabbitTemplate getRabbitTemplate() {
Message.addWhiteListPatterns(RabbitConstants.CLASSES_TO_SEND_OVER_RABBITMQ);
return new RabbitTemplate(this.connectionFactory());
}
/**
* Define the RabbitErrorHandle
* @return Initialize RabbitErrorHandle bean
*/
@Bean
public RabbitErrorHandler rabbitErrorHandler() {
return new RabbitErrorHandler();
}
}
Create the @RabbitListner with parameters where rabbitErrorHandler is the bean that I defined previously :
@Override
@RabbitListener(queues = "${rabbit.queue}"
, errorHandler = "rabbitErrorHandler"
, returnExceptions = "true")
public ReturnObject receiveMessage(Message message) {
For the RabbitTemplate I set this attribute :
rabbitTemplate.setMessageConverter(new RemoteInvocationAwareMessageConverterAdapter());
When the messsage threated by the consumer, but it sent an error, I obtain a RemoteInvocationResult which contains the original exception into e.getCause().getCause().
See the returnExceptions
property on @RabbitListener
(since 2.0). Docs here.
The
returnExceptions
attribute, whentrue
will cause exceptions to be returned to the sender. The exception is wrapped in aRemoteInvocationResult
object.On the sender side, there is an available
RemoteInvocationAwareMessageConverterAdapter
which, if configured into theRabbitTemplate
, will re-throw the server-side exception, wrapped in anAmqpRemoteException
. The stack trace of the server exception will be synthesized by merging the server and client stack traces.Important
This mechanism will generally only work with the default SimpleMessageConverter, which uses Java serialization; exceptions are generally not "Jackson-friendly" so can’t be serialized to JSON. If you are using JSON, consider using an errorHandler to return some other Jackson-friendly Error object when an exception is thrown.