Hi Matthias, To sum up with the ProductionExceptionHandler callback methods (106) proposed changes.
A new method ProductionExceptionHandler#handle is added with the following signature: > ProductionExceptionHandlerResponse handle(final ErrorHandlerContext context, > final ProducerRecord<?,?> record, final Exception exception); The ProducerRecord<?,?> parameter has changed to accept a serialized or non-serialized record. Thus, the new ProductionExceptionHandler#handle method can handle both production exception and serialization exception. Both old ProductionExceptionHandler#handle and ProductionExceptionHandler#handleSerializationException methods are now deprecated. The old ProductionExceptionHandler#handle method gets a default implementation, so users do not have to implement a deprecated method. To handle backward compatibility, the new ProductionExceptionHandler#handle method gets a default implementation. > default ProductionExceptionHandlerResponse handle(final ErrorHandlerContext > context, final ProducerRecord<?, ?> record, final Exception exception) { > if (exception instanceof RecordSerializationException) { > this.handleSerializationException(record, exception.getCause()); > } > > return handle((ProducerRecord<byte[], byte[]>) record, exception); > } The default implementation either invokes #handleSerializationException or #handle depending on the type of the exception, thus users still relying on deprecated ProductionExceptionHandler#handle or ProductionExceptionHandler#handleSerializationException custom implementations won't break. The new ProductionExceptionHandler#handle method is now invoked in case of serialization exception: > public <K, V> void send(final String topic, final K key, final V value, ...) { > try { > keyBytes = keySerializer.serialize(topic, headers, key); > ... > } catch (final ClassCastException exception) { > ... > } catch (final Exception exception) { > > try { > response = productionExceptionHandler.handle(context, record, new > RecordSerializationException(SerializationExceptionOrigin.KEY, exception)); > } catch (final Exception e) { > ... > } > } > } To wrap the origin serialization exception and determine whether it comes from the key or the value, a new exception class is created: > public class RecordSerializationException extends SerializationException { > public enum SerializationExceptionOrigin { > KEY, > VALUE > } > > public RecordSerializationException(SerializationExceptionOrigin origin, > final Throwable cause); > } Hope it all makes sense, Loïc