Skip to content

Commit

Permalink
PI-1478 changes to retry exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
stevomcallister committed Sep 21, 2023
1 parent d5c7457 commit a297dd0
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 6 deletions.
1 change: 1 addition & 0 deletions libs/commons/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ dependencies {
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation(libs.bundles.telemetry)
implementation(libs.flipt)
implementation(libs.openfeign)

testImplementation("org.springframework.boot:spring-boot-starter-data-ldap")
testImplementation("org.springframework.boot:spring-boot-starter-test")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
package uk.gov.justice.digital.hmpps.retry

fun <T> retry(maxRetries: Int, code: () -> T): T {
var throwable: Throwable? = null
(1..maxRetries).forEach { _ ->
import kotlin.reflect.KClass

fun <T> retry(maxRetries: Int, exceptions: List<KClass<out Exception>> = listOf(Exception::class), code: () -> T): T {
var throwable: Throwable?
(1..maxRetries).forEach { count ->
try {
return code()
} catch (e: Throwable) {
throwable = e
val matchedException = exceptions.firstOrNull { it.isInstance(e) }
throwable = if (matchedException != null && count < maxRetries) {
null
} else {
e
}

if (throwable != null) {
throw throwable!!
}
}
}
throw throwable!!
throw RuntimeException("unknown error")
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package uk.gov.justice.digital.hmpps.retry

import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.json.JSONException
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.springframework.dao.OptimisticLockingFailureException
import java.rmi.UnexpectedException
import java.sql.SQLException
import java.util.concurrent.atomic.AtomicInteger

internal class RetryTest {
Expand All @@ -29,4 +32,29 @@ internal class RetryTest {
}
assertThat(result, equalTo(1))
}

@Test
fun `when optimistic lock exception thrown retry until max retries`() {
val counter = AtomicInteger(0)
assertThrows<OptimisticLockingFailureException> {
retry(3, listOf(OptimisticLockingFailureException::class, JSONException::class)) {
counter.incrementAndGet()
throw OptimisticLockingFailureException("OLE")
}
}
assertThat(counter.get(), equalTo(3))
}

@Test
fun `when SQL exception thrown no retries`() {
val counter = AtomicInteger(0)
assertThrows<SQLException> {
retry(3, listOf(OptimisticLockingFailureException::class)) {
counter.incrementAndGet()
throw SQLException("SQLE")
}
}
assertThat(counter.get(), equalTo(1))
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.springframework.context.annotation.Conditional
import org.springframework.stereotype.Component
import uk.gov.justice.digital.hmpps.config.AwsCondition
import uk.gov.justice.digital.hmpps.messaging.NotificationHandler
import uk.gov.justice.digital.hmpps.retry.retry
import java.util.concurrent.CompletionException

@Component
Expand All @@ -25,7 +26,12 @@ class AwsNotificationListener(
@WithSpan(kind = SpanKind.CONSUMER)
fun receive(message: String) {
try {
handler.handle(message)
retry(3,listOf(ObjectOptimisticLockingFailureException::class,
ConstraintViolationException::class,
RetryableException::class,
CannotCreateTransactionException::class,
FeignException.NotFound::class,
CannotGetJdbcConnectionException::class,)) { handler.handle(message) }
} catch (e: Throwable) {
Sentry.captureException(unwrapSqsExceptions(e))
throw e
Expand Down

0 comments on commit a297dd0

Please sign in to comment.