Error handling in clients in Kafka - Time & Space Complexity
When clients handle errors in Kafka, the time it takes to respond can change depending on how errors are managed.
We want to see how the time spent grows as the number of messages or errors increases.
Analyze the time complexity of the following code snippet.
consumer.poll(Duration.ofMillis(100)).forEach(record -> {
try {
process(record);
} catch (Exception e) {
handleError(e, record);
}
});
This code polls messages and processes each one, catching errors to handle them immediately.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping over each message returned by poll.
- How many times: Once per message in the batch.
As the number of messages increases, the processing and error handling happen for each message.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 process and error checks |
| 100 | About 100 process and error checks |
| 1000 | About 1000 process and error checks |
Pattern observation: The work grows directly with the number of messages.
Time Complexity: O(n)
This means the time to handle messages and errors grows in a straight line as more messages come in.
[X] Wrong: "Error handling only happens once, so it doesn't add to the time."
[OK] Correct: Error handling runs for each message that causes an error, so it adds time for every such message.
Understanding how error handling affects processing time helps you write reliable Kafka clients and explain your code clearly in interviews.
"What if error handling involved retrying the message multiple times? How would the time complexity change?"
Practice
Solution
Step 1: Understand error handling role
Error handling helps the client manage unexpected problems without crashing.Step 2: Identify the main goal in Kafka clients
Keeping the client stable and responsive ensures smooth operation even if errors occur.Final Answer:
To keep the client stable and responsive during failures -> Option BQuick Check:
Error handling = stability and responsiveness [OK]
- Thinking error handling speeds up processing
- Confusing error handling with message size control
- Assuming error handling creates topics automatically
Solution
Step 1: Identify correct Java try-catch syntax
Java requires try { ... } catch (Exception e) { ... } to handle exceptions.Step 2: Match syntax with Kafka producer send call
try { producer.send(record); } catch (Exception e) { e.printStackTrace(); } correctly wraps the send call in try-catch block.Final Answer:
try { producer.send(record); } catch (Exception e) { e.printStackTrace(); } -> Option CQuick Check:
Java try-catch syntax = try { producer.send(record); } catch (Exception e) { e.printStackTrace(); } [OK]
- Using if-else instead of try-catch for exceptions
- Using JavaScript syntax in Java code
- Missing braces in try-catch block
try {
ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
for (var record : records) {
System.out.println(record.value());
}
} catch (WakeupException e) {
System.out.println("Consumer interrupted");
} catch (Exception e) {
System.out.println("Error during poll");
}Solution
Step 1: Identify exception types caught
WakeupException prints "Consumer interrupted"; all other exceptions print "Error during poll".Step 2: Determine exception for network error
Network errors throw general exceptions, not WakeupException.Final Answer:
Error during poll -> Option AQuick Check:
Network error triggers general Exception = Error during poll [OK]
- Confusing WakeupException with network errors
- Expecting no output on error
- Assuming stack trace prints automatically
try {
producer.send(record);
} catch (KafkaException e) {
System.out.println("Error sending message");
}
producer.close();Solution
Step 1: Check resource cleanup
producer.close() must run regardless of exceptions to free resources.Step 2: Use finally block for cleanup
Placing close() inside finally ensures it always executes.Final Answer:
producer.close() should be inside finally block -> Option DQuick Check:
Always close resources in finally block [OK]
- Closing producer only on success
- Catching too broad or wrong exceptions
- Assuming send() never throws exceptions
Solution
Step 1: Understand retry logic requirements
Retry polling up to 3 times on recoverable errors, then stop and log.Step 2: Identify correct control flow
Loop with try-catch, count retries, break after 3 attempts, and close consumer in finally block is correct.Final Answer:
Use a loop with try-catch around poll; on exception increment retry count; break after 3 retries; finally close consumer -> Option AQuick Check:
Retry with loop and try-catch = Use a loop with try-catch around poll; on exception increment retry count; break after 3 retries; finally close consumer [OK]
- Not retrying on recoverable errors
- Ignoring exceptions and continuing endlessly
- Closing consumer too early without retries
Ready to prove it?
Pass the test and this pattern moves unknown
