Class ForeverRetryingErrorHandler

java.lang.Object
io.fluxzero.sdk.tracking.RetryingErrorHandler
io.fluxzero.sdk.tracking.ForeverRetryingErrorHandler
All Implemented Interfaces:
ErrorHandler

public class ForeverRetryingErrorHandler extends RetryingErrorHandler
A RetryingErrorHandler with no retry-count limit for eligible failures.

Start with the default LoggingErrorHandler. Choose unlimited retries when an effect must survive a recoverable outage before processing can advance, and repeating the operation is safe. Examples include replacing a search document by stable ID or reconciling schedules from durable current intent. Every completed side effect must be idempotent; an uncertain remote outcome can still have taken effect.

Operational cost: the affected tracker/batch waits while retries continue. A permanent failure can therefore block progress indefinitely and grow the backlog. Monitor lag and retry failures, and provide a way to repair a poison message or its cause. This policy does not itself guarantee delivery or exactly-once effects.

Retry boundaries:

  • The initial errorFilter defaults to excluding FunctionalException. An excluded initial error is logged and returned without retry; tracking may continue.
  • The first retry is immediate. After failed retries, default backoff starts at 10 seconds and caps at 1 minute.
  • The initial filter is not reapplied to later failures. The separate RetryConfiguration error test controls failures during retries and excludes Error by default. A functional failure on a later attempt can therefore keep retrying.
  • Interruption or a rejected retry failure can end the loop. A rejected retry failure returns null by default; interruption normally returns the mapped original error. These paths do not deliberately stop the consumer. Custom filters, mappers or logging can themselves throw.

Explicit opt-in:

@Consumer(name = "reconciled-projection", errorHandler = ForeverRetryingErrorHandler.class)
public class ReconciledProjection {
    @HandleEvent
    void on(ItemChanged event) {
        // Replace the projection by stable ID; alert on sustained retry/consumer lag
    }
}
See Also:
  • Constructor Details

    • ForeverRetryingErrorHandler

      public ForeverRetryingErrorHandler()
      Constructs a ForeverRetryingErrorHandler with capped exponential backoff, starting at 10 seconds and capped at 1 minute, retrying non-functional errors and logging both functional and technical failures.
    • ForeverRetryingErrorHandler

      public ForeverRetryingErrorHandler(Duration delay, Predicate<Throwable> errorFilter, boolean logFunctionalErrors, Function<Throwable, ?> errorMapper)
      Constructs a ForeverRetryingErrorHandler with custom delay, error filtering, logging, and error mapping.
      Parameters:
      delay - the delay between retries
      errorFilter - predicate to select which errors should trigger retries
      logFunctionalErrors - whether to log functional errors
      errorMapper - maps an excluded initial error or an error after the retry loop terminates into a result
    • ForeverRetryingErrorHandler

      public ForeverRetryingErrorHandler(RetryConfiguration retryConfiguration)
      Constructs a ForeverRetryingErrorHandler with a custom retry configuration, retrying non-functional errors and logging both functional and technical failures.
      Parameters:
      retryConfiguration - retry delay strategy, logging callbacks, and error mapping
    • ForeverRetryingErrorHandler

      public ForeverRetryingErrorHandler(RetryConfiguration retryConfiguration, Predicate<Throwable> errorFilter, boolean logFunctionalErrors)
      Constructs a ForeverRetryingErrorHandler with a custom retry configuration. The configured maximum number of retries is ignored and changed to unlimited to preserve the contract of this handler.
      Parameters:
      retryConfiguration - retry delay strategy, logging callbacks, and error mapping
      errorFilter - predicate to select which errors should trigger retries
      logFunctionalErrors - whether to log functional errors