handleUDXOperation<T> static method

Future<T> handleUDXOperation<T>(
  1. Future<T> operation(),
  2. String context, {
  3. UDXRetryConfig retryConfig = UDXRetryConfig.regular,
  4. bool shouldRetry(
    1. dynamic error
    )?,
})

Handles UDX operations with comprehensive exception handling and retry logic

Implementation

static Future<T> handleUDXOperation<T>(
  Future<T> Function() operation,
  String context, {
  UDXRetryConfig retryConfig = UDXRetryConfig.regular,
  bool Function(dynamic error)? shouldRetry,
}) async {
  int attempt = 0;
  Duration delay = retryConfig.initialDelay;

  while (attempt <= retryConfig.maxRetries) {
    try {
      _logger.fine('[UDXExceptionHandler] Executing operation: $context (attempt ${attempt + 1}/${retryConfig.maxRetries + 1})');
      return await operation();
    } catch (error, stackTrace) {
      final classifiedException = classifyUDXException(error, context, stackTrace);

      // If this is the last attempt or error is not retryable, throw
      if (attempt >= retryConfig.maxRetries ||
          !shouldRetryError(classifiedException, shouldRetry)) {
        _logger.warning('[UDXExceptionHandler] Operation failed permanently: $context. Error: $classifiedException');
        throw classifiedException;
      }

      // Log retry attempt
      _logger.info('[UDXExceptionHandler] Operation failed, retrying: $context. Attempt ${attempt + 1}/${retryConfig.maxRetries + 1}. Error: $classifiedException');

      // Calculate delay with exponential backoff and optional jitter
      if (retryConfig.enableJitter) {
        final jitter = _random.nextDouble() * 0.1; // 10% jitter
        delay = Duration(
          milliseconds: (delay.inMilliseconds * (1 + jitter)).round(),
        );
      }

      await Future.delayed(delay);

      // Update delay for next iteration
      delay = Duration(
        milliseconds: (delay.inMilliseconds * retryConfig.backoffMultiplier).round(),
      );
      if (delay > retryConfig.maxDelay) {
        delay = retryConfig.maxDelay;
      }

      attempt++;
    }
  }

  // This should never be reached, but just in case
  throw UDXTransportException('Max retries exceeded', context, null);
}