Last active
April 27, 2023 00:02
-
-
Save felipecsl/4323dada0db6e74d8757a756b254f45d to your computer and use it in GitHub Desktop.
Kotlin utility to retry a provided block a limited number of times
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Retries the provided [block] up to [times] times if the block throws an exception of the type | |
* [exceptionType]. If any other exception type is thrown, the exception is caught and then | |
* immediately rethrown. | |
*/ | |
fun retryIfThrown(times: Int, exceptionType: KClass<out Throwable>, block: () -> Unit) { | |
for (i in 0 until times) { | |
try { | |
block() | |
break | |
} catch (e: Throwable) { | |
if (e.javaClass.kotlin == exceptionType && i < times - 1) { | |
println("Caught ${exceptionType.simpleName}, message=`${e.message}`. Retrying ${i + 1}/$times") | |
} else { | |
throw e | |
} | |
} | |
} | |
} | |
class UtilTest { | |
@Test fun `it should not retry`() { | |
var tries = 0 | |
val block: () -> Unit = { | |
tries++ | |
} | |
retryIfThrown(3, RuntimeException::class, block) | |
assertThat(tries).isEqualTo(1) | |
} | |
@Test fun `it should retry twice`() { | |
var tries = 0 | |
val block = { | |
tries++ | |
if (tries < 2) { | |
throw RuntimeException() | |
} | |
} | |
retryIfThrown(3, RuntimeException::class, block) | |
assertThat(tries).isEqualTo(2) | |
} | |
@Test(expected = RuntimeException::class) | |
fun `it should retry 3 times then rethrow the exception`() { | |
var tries = 0 | |
val block = { | |
tries++ | |
throw RuntimeException() | |
} | |
try { | |
retryIfThrown(3, RuntimeException::class, block) | |
} catch (e: Throwable) { | |
assertThat(tries).isEqualTo(3) | |
throw e | |
} | |
} | |
@Test(expected = IllegalArgumentException::class) | |
fun `it should not retry if exception is not of expected type`() { | |
var tries = 0 | |
val block = { | |
tries++ | |
throw IllegalArgumentException() | |
} | |
try { | |
retryIfThrown(3, RuntimeException::class, block) | |
} catch (e: Throwable) { | |
assertThat(tries).isEqualTo(1) | |
throw e | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment