func withRetry[T any]()

in internal/enricher/retry.go [54:96]


func withRetry[T any](ctx context.Context, opts RetryOptions, op func(context.Context) (T, error)) (T, error) {
	var lastErr error
	var result T

	for attempt := 0; attempt < opts.MaxAttempts; attempt++ {
		select {
		case <-ctx.Done():
			if lastErr == nil {
				lastErr = &ErrCancelled{Msg: "operation cancelled by context", Err: ctx.Err()}
			}
			return result, lastErr
		default:
			// Calculate backoff duration
			backoff := opts.InitialBackoff * time.Duration(math.Pow(opts.BackoffMultiplier, float64(attempt)))
			if backoff > opts.MaxBackoff {
				backoff = opts.MaxBackoff
			}

			// Execute operation
			result, lastErr = op(ctx)
			if lastErr == nil {
				return result, nil
			}

			// Check if error is retryable
			if !isRetryableError(lastErr) {
				return result, lastErr
			}
			log.Printf("WARN: Operation failed on attempt %d with error: %v. Retrying in %v...", attempt+1, lastErr, backoff)
			// Wait before next attempt
			timer := time.NewTimer(backoff)
			select {
			case <-ctx.Done():
				timer.Stop()
				return result, &ErrCancelled{Msg: "operation cancelled during backoff", Err: ctx.Err()}
			case <-timer.C:
				continue
			}
		}
	}

	return result, lastErr
}