Status

Current state: "Under Discussion"

Discussion thread: here 

JIRA:

Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).

Motivation

In transactions, having a poison record or sending the record to a topic with issues ends up going to an error state, which leads to dropping the whole batch. This logic does not allow the user to do advanced error handling and ignore some errors. More specifically, the custom production exception handler of Kafka Streams can not influence the control to skip the error by dropping the bad record and committing the transaction with the rest of the batch records.  

Proposed Changes

We aim at enabling users to ignore the `send(ProducerRecord)` errors by explicitly calling `flush()` and the `commitTransaction(ignoreError)` method so that it clears the latest error produced by `send(ProducerRecord)`.  In order to keep it safe, the change is applied to transactions with no pending record. It mean that, if   Therefore, if the user calls `flush()` after a `send`, the error produced by send (if existing) is cleared. 

Public Interfaces


     /**
     * If {@link #flush()} is called explicitly before this method and the input config parameter determines ignoring errors,
     * this method clears the last exception produced by the {@link #send(ProducerRecord)} call and transits the transaction
     * out of error state. Thereupon, the method carries out the same procedures as delineated in {@link #commitTransaction()}.
     *  
     * @param commitOptions The method options
     * @throws IllegalStateException if no transactional.id has been configured or no transaction has been started
     * @throws ProducerFencedException fatal error indicating another producer with the same transactional.id is active
     * @throws org.apache.kafka.common.errors.UnsupportedVersionException fatal error indicating the broker
     *         does not support transactions (i.e. if its version is lower than 0.11.0.0)
     * @throws org.apache.kafka.common.errors.AuthorizationException fatal error indicating that the configured
     *         transactional.id is not authorized. See the exception for more details
     * @throws org.apache.kafka.common.errors.InvalidProducerEpochException if the producer has attempted to produce with an old epoch
     *         to the partition leader. See the exception for more details
     * @throws KafkaException if the producer has encountered a previous fatal or abortable error, or for any
     *         other unexpected error
     * @throws TimeoutException if the time taken for committing the transaction has surpassed <code>max.block.ms</code>.
     * @throws InterruptException if the thread is interrupted while blocked
     */
     public void commitTransaction(Map<String, ?> commitOptions) throws ProducerFencedException {}


Compatibility, Deprecation, and Migration Plan

Since the default behaviour is preserved, the change has no impact on existing users.

Test Plan

Unit tests for `KafkaProducer` to show that the new feature works with different `send()` errors and exceptions such as RecordTooLargeException.

Rejected Alternatives