@SuppressWarnings("squid:S1181")
    // Yes we really do want to catch Throwable
    @Override
    public V apply(U input) {
        int retryAttempts = 0;
        while (true) {
            try {
                return baseFunction.apply(input);
            } catch (Throwable t) {
                if (!exceptionClass.isAssignableFrom(t.getClass()) || retryAttempts == maxRetries) {
                    Throwables.throwIfUnchecked(t);
                    throw new RetriesExceededException(t);
                }
                Tools.randomDelay(maxDelayBetweenRetries);
                retryAttempts++;
            }
        }
    }
@Test(expected = RetryableException.class)
    public void testFailureAfterOneRetry() {
        new RetryingFunction<>(this::succeedAfterTwoFailures, RetryableException.class, 1, 10).apply(null);
    }