spring-amqp
spring-amqp copied to clipboard
Feature: Option for @RabbitListener to Not Retry on Fatal Exception
Based on my understanding, and what I saw, the @RabbitListener
will retry even if a thrown exception is fatal per ConditionalRejectingErrorHandler.DefaultExceptionStrategy
. There are many cases where it does not make sense to retry, like when the JSON in the message is not valid. There is no reason to try again, in this case. Therefore, it would be great for there to be an option, or some other way, out-of-the-box, to not reprocess the incoming message if the @RabbitListener
errored in a way that does not make sense to retry.
The current workaround I came up with was to implement a RabbitRetryTemplateCustomizer
which has an injected FatalExceptionStrategy
, and customize the retry policy to check if the exception is fatal.
I would say we can't make such an unconditioanl decision in the framework and some customized RetryPolicy
is the way to go.
We definitely may provide some out-of-the-box RetryPolicy
based on your condition, but it won't make it as a default one anyway.
Does it make sense?
Thank you!
Does it make sense?
Yes, absolutely that makes sense. I am not suggesting that no-retry be the default.
Good. So, feel free to contribute such a custom RetryPolicy
!
https://stackoverflow.com/a/75652127
@marcusvoltolim ,
Do you suggest that SimpleRetryPolicy
covers such a use-case?
From what I understand, yes! Just add a Map with the exceptions and false so that they are not retried and defaultValue=true
See one more constructor for that SimpleRetryPolicy:
/**
* Create a {@link SimpleRetryPolicy} with the specified number of retry attempts. If
* traverseCauses is true, the exception causes will be traversed until a match or the
* root cause is found. The default value indicates whether to retry or not for
* exceptions (or super classes thereof) that are not found in the map.
* @param maxAttempts the maximum number of attempts
* @param retryableExceptions the map of exceptions that are retryable based on the
* map value (true/false).
* @param traverseCauses true to traverse the exception cause chain until a classified
* exception is found or the root cause is reached.
* @param defaultValue the default action.
*/
public SimpleRetryPolicy(int maxAttempts, Map<Class<? extends Throwable>, Boolean> retryableExceptions,
boolean traverseCauses, boolean defaultValue) {...}
Good. Closing as Not Planned
.
Other option:
public class IgnoreFatalErrorSimpleRetryPolicy extends SimpleRetryPolicy {
private static final FatalExceptionStrategy exceptionStrategy =
new ConditionalRejectingErrorHandler.DefaultExceptionStrategy();
public IgnoreFatalErrorSimpleRetryPolicy(int maxAttempts) {
super(maxAttempts);
}
@Override
public boolean canRetry(RetryContext context) {
return !exceptionStrategy.isFatal(context.getLastThrowable()) && super.canRetry(context);
}
}