/** * Curries a {@link ExceptionHandler} with a specific error {@code summary}, so that it can be used * as a simpler {@link Throwable} {@link Consumer}. * * @param summary The error summary to feed to the {@code exceptionHandler}. * @param exceptionHandler Handles errors. * @return A curried {@link Throwable} {@link Consumer}. */ public static Consumer<Throwable> withSummary(String summary, ExceptionHandler exceptionHandler) { return cause -> exceptionHandler.onException(summary, cause); }
@Override public Joinable terminate() { if (leaseCandidate != null) { deactivate(ExceptionHandler.nop()); } Terminator.blank() .add(Optional.ofNullable(receiver)) .add(Optional.ofNullable(keeperThread)) .add(Optional.ofNullable(election)) .terminate(); return this; }
private void sendNow(ProducerRecord<K, V> record, Callback callback) { try { producer.send(record, callback); } catch (Throwable e) { if (! producerDisposed) { exceptionHandler.onException(String.format("Error sending %s", record), e); } } }
private static void doWithExceptionHandler(CheckedRunnable<?> r, ExceptionHandler errorHandler, String message) { try { r.run(); } catch (Throwable e) { errorHandler.onException(message, e); } }
private void cycle(WorkerThread thread) throws InterruptedException { try { final ConsumerRecords<K, V> records = consumer.poll(Duration.ofMillis(pollTimeoutMillis)); recordHandler.onReceive(records); } catch (InterruptedException e) { throw e; } catch (org.apache.kafka.common.errors.InterruptException e) { throw new InterruptedException("Converted from " + org.apache.kafka.common.errors.InterruptException.class.getName()); } catch (Throwable e) { exceptionHandlerHandler.onException("Unexpected error", e); return; } }
public <T, X extends Throwable> T run(CheckedSupplier<? extends T, X> operation) throws X { for (int attempt = 0;; attempt++) { try { return operation.get(); } catch (Throwable e) { if (exceptionMatcher.test(e)) { if (attempt == attempts - 1) { final String faultMessage = String.format("Fault (attempt #%,d of %,d): aborting", attempt + 1, attempts); errorHandler.onException(faultMessage, e); throw e; } else { final String retryMessage = String.format("Fault (attempt #%,d of %,d): retrying in %,d ms", attempt + 1, attempts, backoffMillis); faultHandler.onException(retryMessage, e); if (! Threads.sleep(backoffMillis)) { final String interruptMessage = String.format("Fault (attempt #%,d of %,d): aborting due to interrupt", attempt + 1, attempts); errorHandler.onException(interruptMessage, e); throw e; } } } else { throw e; } } } } }
private void putOffset(long offset) { if (isCurrentTenant()) { doWithExceptionHandler(() -> offsets.put(config.getGroup(), offset), config.getExceptionHandler(), "Failed to update offset"); } else { final String m = String.format("Failed confirming offset %s for stream %s: %s is not the current tenant for group %s", offset, config.getStreamConfig().getName(), leaseCandidate, config.getGroup()); config.getExceptionHandler().onException(m, null); } }
final String m = String.format("Error reading at offset %,d from stream %s [%s]", nextReadOffset, config.getStreamConfig().getName(), serviceInfo); config.getExceptionHandler().onException(m, e.getCause()); f.cancel(true); Thread.sleep(waitMillis);