flybywire
flybywire

Reputation: 274002

jms error handler: receive a callback only when jms gives up

I am using spring-jms with active mq.

I have a ErrorHandler listener set up, that receives a callback each time a jms message delivery fails - i.e. the method that processes the message throws an exception instead of returning gracefully.

However my jms is configured to retry several times until the jms delivery finally succeeds. And my callback is notified of all of the failures.

What I want is a listener that receives a notification only when all the retries finally fail. The motivation is to bring the issue up for the admin's attention. But I don't want spurious notifications in the admin's console.

<bean abstract="true" id="abstractDestinationListener"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsFactory" />
    <property name="errorHandler" ref="destinationErrorHandler"/>
    <property name="sessionTransacted" value="true"/>
</bean>

Upvotes: 5

Views: 3319

Answers (2)

Jakub Korab
Jakub Korab

Reputation: 5034

There are two options you could consider:

1. DLQ with consumer
Use a per-destination dead-letter queue for the destinations in question (individualDeadLetterStrategy - https://activemq.apache.org/message-redelivery-and-dlq-handling.html). When the maximum redelivery count has been hit, the message is moved out to the DLQ. You can then set up a consumer on that queue with a listener that emails the administrator.

2. Don't throw an exception when max redelivery count is exceeded
Wrap your listener with a try-catch and rethrow any exceptions only if the max redelivery count is not yet reached; otherwise sent the email instead:

@Value("${config.max-redelivery-count}")
private String maxRedeliveryCount;

@JmsListener(destination = "..")
public void onMessage(Message message) throws JMSException {
  boolean isLastAttempt = message.getIntProperty("JMSXDeliveryCount") > maxRedeliveryCount;

  try {
    // do normal flow
  } catch (Exception e) {
    if (isLastAttempt) {
      sendEmail(..);
    } else {
      throw e;
    }
  }
}

However, that option means placing your redelivery limit in two places - the broker config and the code.

Upvotes: 4

Ben ODay
Ben ODay

Reputation: 21015

if you need more fine-grained control/flexibility/routing with JMS messaging/handling, then you should just use Apache Camel's error handling...

Upvotes: 0

Related Questions