-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Add an option to traverse the cause chain to find a delegate.
Discussed in #2283
Originally posted by amseager May 25, 2022
Currently, everything in this handler uses this private method:
@Nullable
private CommonErrorHandler findDelegate(Throwable thrownException) {
Throwable cause = thrownException;
if (cause instanceof ListenerExecutionFailedException) {
cause = thrownException.getCause();
}
if (cause != null) {
Class<? extends Throwable> causeClass = cause.getClass();
for (Entry<Class<? extends Throwable>, CommonErrorHandler> entry : this.delegates.entrySet()) {
if (entry.getKey().isAssignableFrom(causeClass)) {
return entry.getValue();
}
}
}
return null;
}
As you can see, if we have ListenerExecutionFailedException
, we'll get its cause and find an appropriate delegate.
However, this wouldn't work in a lot of cases when we have our set of exceptions wrapped in something else, e.g. in MessageConversionException
(I think it's the most popular case). And we cannot use MessageConversionException
as a delegates
map key since we want to have a different logic for each underlying exception (let's say we want custom DefaultErrorHandler
for ConstraintViolationException
with a fixed backoff and its own recoverer and the another one for any other exception with ExponentialBackOff
without a recoverer at all - but both are wrapped in the same MessageConversionException
).
How to solve this problem? I don't want to write a custom DelegatingErrorHandler because I'll need to copy almost all the code from the CommonDelegatingErrorHandler
.
Previously, we had ConditionalDelegatingErrorHandler
which had handle
method being public so it could've been ok to override it but now it's deprecated in favor of CommonDelegatingErrorHandler
.