The main goal of this project is to show how to configure global error handling for exceptions occurred during receiving them on the listeners (getting from the queue).
On the rabbitmq queue appears a message that cannot be parsed to the dtos over the appropriate listener (for example - has completely different structure or some fields has other type or it could have no structure at all - because AMQP propagate byte-body messages) we want to log it.
GlobalErrorConfig
:@Configuration
class that producesorg.springframework.util.ErrorHandler
bean.RejectingErrorHandler
: extension oforg.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler.DefaultExceptionStrategy
-
in
isFatal
we perform logging action (only in case ofListenerExecutionFailedException
)Remark: only if
isFatal
returns true a message is removed from a queue -
in
isUserCauseFatal
we define all exception as fatal
-
ConditionalRejectingErrorHandler.DefaultExceptionStrategy
:
isFatal
:@Override public boolean isFatal(Throwable t) { Throwable cause = t.getCause(); while (cause instanceof MessagingException && !(cause instanceof org.springframework.messaging.converter.MessageConversionException) && !(cause instanceof MethodArgumentResolutionException)) { cause = cause.getCause(); } if (t instanceof ListenerExecutionFailedException && isCauseFatal(cause)) { if (this.logger.isWarnEnabled()) { this.logger.warn( "Fatal message conversion error; message rejected; " + "it will be dropped or routed to a dead letter exchange, if so configured: " + ((ListenerExecutionFailedException) t).getFailedMessage()); } return true; } return false; }
isCauseFatal
private boolean isCauseFatal(Throwable cause) { return cause instanceof MessageConversionException || cause instanceof org.springframework.messaging.converter.MessageConversionException || cause instanceof MethodArgumentResolutionException || cause instanceof NoSuchMethodException || cause instanceof ClassCastException || isUserCauseFatal(cause); }
isUserCauseFatal
protected boolean isUserCauseFatal(Throwable cause) { return false; }