-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Spring Kafka version
3.3.5
TL;DR;
Clarify Handling Exceptions and mention that only RuntimeException
will be handled. Throwing something that inherits from Error
, like what happens if you use Kotlins TODO()
helper, will cause the consumer to exit and close.
Problem:
The Handling Exceptions > DefaultErrorHandler documentation says:
The DefaultErrorHandler considers certain exceptions to be fatal, and retries are skipped for such exceptions; the recoverer is invoked on the first failure. The exceptions that are considered fatal, by default, are:
DeserializationException MessageConversionException ConversionException MethodArgumentResolutionException NoSuchMethodException ClassCastException
That is correct but also a bit misleading. 😅 DefaultErrorHandler
will indeed treat those as fatal, non-recoverable, exceptions but the catch statement in KafkaMessageListenerContainer
means only throwable that inherits from RuntimeException
will reach the error handler and be handled gracefully.
Line 2781 in bb6280c
catch (RuntimeException e) { |
If the code throws something inheriting from Error
, like the TODO()
kotlin helper that the Intellij IDE uses for on auto-generated method stubs do, then we will end up in the outer Error e
handler which will cause the consumer loop to shutdown leading to a application that is "alive" according to Spring Boot Actuator yet have a closed Kafka consumer.
Lines 1380 to 1385 in bb6280c
catch (Error e) { // NOSONAR - rethrown | |
this.logger.error(e, "Stopping container due to an Error"); | |
this.fatalError = true; | |
wrapUp(e); | |
throw e; | |
} |
Context
A IDE generate method stub that used the TODO()
kotlin function ended up in production. Since it inherits from Error
and not from RuntimeException
we ended up with a spring boot app that reported Status: OK
but had a dead kafka consumer.