protected static final void logAndThrowMessageError(final Message message, final String error) { LOGGER.warn("Warning! \"{}\" reported by message: {}", error, message); throw new AmqpRejectAndDontRequeueException(error); }
@Override public void recover(Message message, Throwable cause) { if (this.logger.isWarnEnabled()) { this.logger.warn("Retries exhausted for message " + message, cause); } throw new ListenerExecutionFailedException("Retry Policy Exhausted", new AmqpRejectAndDontRequeueException(cause), message); }
< 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. } }
@Override public void recover(Message message, Throwable cause) { if (this.logger.isWarnEnabled()) { this.logger.warn("Retries exhausted for message " + message, cause); } throw new ListenerExecutionFailedException("Retry Policy Exhausted", new AmqpRejectAndDontRequeueException(cause), message); }
@Override public void handleMessage(org.springframework.messaging.Message<?> message) throws MessagingException { Message amqpMessage = (Message) message.getHeaders() .get(AmqpMessageHeaderErrorMessageStrategy.AMQP_RAW_MESSAGE); /* * NOTE: The following IF and subsequent ELSE IF should never happen under normal interaction and * it should always go to the last ELSE * However, given that this is a handler subscribing to the public channel and that we can't control what * type of Message may be sent to that channel (user decides to send a Message manually) the 'IF/ELSE IF' provides * a safety net to handle any message properly. */ if (!(message instanceof ErrorMessage)) { logger.error("Expected an ErrorMessage, not a " + message.getClass().toString() + " for: " + message); throw new ListenerExecutionFailedException("Unexpected error message " + message, new AmqpRejectAndDontRequeueException(""), null); } else if (amqpMessage == null) { logger.error("No raw message header in " + message); throw new ListenerExecutionFailedException("Unexpected error message " + message, new AmqpRejectAndDontRequeueException(""), amqpMessage); } else { this.recoverer.recover(amqpMessage, (Throwable) message.getPayload()); } }
@Override public void handleMessage(org.springframework.messaging.Message<?> message) throws MessagingException { Message amqpMessage = (Message) message.getHeaders() .get(AmqpMessageHeaderErrorMessageStrategy.AMQP_RAW_MESSAGE); /* * NOTE: The following IF and subsequent ELSE IF should never happen under normal interaction and * it should always go to the last ELSE * However, given that this is a handler subscribing to the public channel and that we can't control what * type of Message may be sent to that channel (user decides to send a Message manually) the 'IF/ELSE IF' provides * a safety net to handle any message properly. */ if (!(message instanceof ErrorMessage)) { logger.error("Expected an ErrorMessage, not a " + message.getClass().toString() + " for: " + message); throw new ListenerExecutionFailedException("Unexpected error message " + message, new AmqpRejectAndDontRequeueException(""), null); } else if (amqpMessage == null) { logger.error("No raw message header in " + message); throw new ListenerExecutionFailedException("Unexpected error message " + message, new AmqpRejectAndDontRequeueException(""), amqpMessage); } else { this.recoverer.recover(amqpMessage, (Throwable) message.getPayload()); } }
protected static void checkContentTypeJson(final Message message) { final MessageProperties messageProperties = message.getMessageProperties(); if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) { return; } throw new AmqpRejectAndDontRequeueException("Content-Type is not JSON compatible"); }
@Test public void testDontRequeueNested() throws Exception { Exception ex = new RuntimeException(new RuntimeException(new AmqpRejectAndDontRequeueException("fail"))); testRequeueOrNotDefaultYes(ex, false); }
@Test public void testDontRequeueNestedDefaultNot() throws Exception { Exception ex = new RuntimeException(new RuntimeException(new AmqpRejectAndDontRequeueException("fail"))); testRequeueOrNotDefaultNo(ex, false); }
@Override public void onMessage(Message message) { if (logger.isTraceEnabled()) { logger.trace("Message received " + message); } String messageTag; if (this.correlationKey == null) { // using standard correlationId property messageTag = message.getMessageProperties().getCorrelationId(); } else { messageTag = (String) message.getMessageProperties() .getHeaders().get(this.correlationKey); } if (messageTag == null) { throw new AmqpRejectAndDontRequeueException("No correlation header in reply"); } PendingReply pendingReply = this.replyHolder.get(messageTag); if (pendingReply == null) { if (logger.isWarnEnabled()) { logger.warn("Reply received after timeout for " + messageTag); } throw new AmqpRejectAndDontRequeueException("Reply received after timeout"); } else { restoreProperties(message, pendingReply); pendingReply.reply(message); } }
@Override public void onMessage(Message message) { if (logger.isTraceEnabled()) { logger.trace("Message received " + message); } String messageTag; if (this.correlationKey == null) { // using standard correlationId property messageTag = message.getMessageProperties().getCorrelationId(); } else { messageTag = (String) message.getMessageProperties() .getHeaders().get(this.correlationKey); } if (messageTag == null) { throw new AmqpRejectAndDontRequeueException("No correlation header in reply"); } PendingReply pendingReply = this.replyHolder.get(messageTag); if (pendingReply == null) { if (logger.isWarnEnabled()) { logger.warn("Reply received after timeout for " + messageTag); } throw new AmqpRejectAndDontRequeueException("Reply received after timeout"); } else { restoreProperties(message, pendingReply); pendingReply.reply(message); } }
@RabbitListener(id = "defaultDLX", bindings = @QueueBinding( value = @Queue(value = "amqp656", autoDelete = "true", arguments = { @Argument(name = "x-dead-letter-exchange", value = ""), @Argument(name = "x-dead-letter-routing-key", value = "amqp656dlq"), @Argument(name = "test-empty", value = ""), @Argument(name = "test-null", value = "") }), exchange = @Exchange(value = "amq.topic", type = "topic"), key = "foo")) public String handleWithDeadLetterDefaultExchange(String foo) { throw new AmqpRejectAndDontRequeueException("dlq"); }
/** * Executed on an authentication request. * * @param message * the amqp message * @return the rpc message back to supplier. */ @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.authenticationReceiverQueue:authentication_receiver}", containerFactory = "listenerContainerFactory") public Message onAuthenticationRequest(final Message message) { checkContentTypeJson(message); final SecurityContext oldContext = SecurityContextHolder.getContext(); try { return handleAuthenticationMessage(message); } catch (final RuntimeException ex) { throw new AmqpRejectAndDontRequeueException(ex); } finally { SecurityContextHolder.setContext(oldContext); } }
@RabbitListener(queues = "${multiplication.queue}") void handleMultiplicationSolved(final MultiplicationSolvedEvent event) { log.info("Multiplication Solved Event received: {}", event.getMultiplicationResultAttemptId()); try { gameService.newAttemptForUser(event.getUserId(), event.getMultiplicationResultAttemptId(), event.isCorrect()); } catch (final Exception e) { log.error("Error when trying to process MultiplicationSolvedEvent", e); // Avoids the event to be re-queued and reprocessed. throw new AmqpRejectAndDontRequeueException(e); } } }
@Override public void onMessage(Message message) { Address replyToAddress = message.getMessageProperties().getReplyToAddress(); if (replyToAddress == null) { throw new AmqpRejectAndDontRequeueException("No replyToAddress in inbound AMQP Message"); } Object invocationRaw = this.messageConverter.fromMessage(message); RemoteInvocationResult remoteInvocationResult; if (!(invocationRaw instanceof RemoteInvocation)) { remoteInvocationResult = new RemoteInvocationResult( new IllegalArgumentException("The message does not contain a RemoteInvocation payload")); } else { RemoteInvocation invocation = (RemoteInvocation) invocationRaw; remoteInvocationResult = invokeAndCreateResult(invocation, getService()); } send(remoteInvocationResult, replyToAddress, message); }
@Override public void handleError(Throwable t) { log(t); if (!this.causeChainContainsARADRE(t) && this.exceptionStrategy.isFatal(t)) { if (this.discardFatalsWithXDeath && t instanceof ListenerExecutionFailedException) { Message failed = ((ListenerExecutionFailedException) t).getFailedMessage(); if (failed != null) { List<Map<String, ?>> xDeath = failed.getMessageProperties().getXDeathHeader(); if (xDeath != null && xDeath.size() > 0) { this.logger.error("x-death header detected on a message with a fatal exception; " + "perhaps requeued from a DLQ? - discarding: " + failed); throw new ImmediateAcknowledgeAmqpException("Fatal and x-death present"); } } } throw new AmqpRejectAndDontRequeueException("Error Handler converted exception to fatal", t); } }
new AmqpRejectAndDontRequeueException("Not retryable; rejecting and not requeuing", ex), messageIn);
@Test public void testDontRequeueDefaultNot() throws Exception { testRequeueOrNotDefaultNo(new AmqpRejectAndDontRequeueException("fail"), false); }
@Test public void testDontRequeue() throws Exception { testRequeueOrNotDefaultYes(new AmqpRejectAndDontRequeueException("fail"), false); }
@Override public void handleError(Throwable t) { log(t); if (!this.causeChainContainsARADRE(t) && this.exceptionStrategy.isFatal(t)) { if (this.discardFatalsWithXDeath && t instanceof ListenerExecutionFailedException) { Message failed = ((ListenerExecutionFailedException) t).getFailedMessage(); if (failed != null) { List<Map<String, ?>> xDeath = failed.getMessageProperties().getXDeathHeader(); if (xDeath != null && xDeath.size() > 0) { this.logger.error("x-death header detected on a message with a fatal exception; " + "perhaps requeued from a DLQ? - discarding: " + failed); throw new ImmediateAcknowledgeAmqpException("Fatal and x-death present"); } } } throw new AmqpRejectAndDontRequeueException("Error Handler converted exception to fatal", t); } }