From 324425a53898069c46916c71f7e38c672bb1f593 Mon Sep 17 00:00:00 2001 From: rsinukov Date: Wed, 22 Feb 2023 19:12:23 +0100 Subject: [PATCH] KTOR-5466 Connect timeout is not respected when using the HttpRequestRetry plugin --- .../io/ktor/client/plugins/HttpRequestRetry.kt | 15 +++++++++++++-- .../io/ktor/client/tests/HttpRequestRetryTest.kt | 5 ++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestRetry.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestRetry.kt index 2f042909db6..716f351c895 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestRetry.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpRequestRetry.kt @@ -6,8 +6,10 @@ package io.ktor.client.plugins import io.ktor.client.* import io.ktor.client.call.* +import io.ktor.client.network.sockets.* import io.ktor.client.request.* import io.ktor.client.statement.* +import io.ktor.client.utils.* import io.ktor.events.* import io.ktor.http.* import io.ktor.util.* @@ -167,14 +169,16 @@ public class HttpRequestRetry internal constructor(configuration: Configuration) /** * Enables retrying a request if an exception is thrown during the [HttpSend] phase * and specifies the number of retries. - * By default, [HttpRequestTimeoutException] is not retried. Set [retryOnTimeout] to `true` to retry on timeout. + * By default, [HttpRequestTimeoutException], [ConnectTimeoutException] and [SocketTimeoutException] + * are not retried. + * Set [retryOnTimeout] to `true` to retry on timeout. * Note, that in this case, [HttpTimeout] plugin should be installed after [HttpRequestRetry]. */ public fun retryOnException(maxRetries: Int = -1, retryOnTimeout: Boolean = false) { retryOnExceptionIf(maxRetries) { _, cause -> when { + cause.isTimeoutException() -> retryOnTimeout cause is CancellationException -> false - cause is HttpRequestTimeoutException && retryOnTimeout -> true else -> true } } @@ -392,3 +396,10 @@ private val RetryDelayPerRequestAttributeKey = AttributeKey Long>( "RetryDelayPerRequestAttributeKey" ) + +private fun Throwable.isTimeoutException(): Boolean { + val exception = unwrapCancellationException() + return exception is HttpRequestTimeoutException + || exception is ConnectTimeoutException + || exception is SocketTimeoutException +} diff --git a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpRequestRetryTest.kt b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpRequestRetryTest.kt index 2ef322bd577..4c3d7b13e61 100644 --- a/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpRequestRetryTest.kt +++ b/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/HttpRequestRetryTest.kt @@ -408,9 +408,8 @@ class HttpRequestRetryTest { } test { client -> - assertFailsWith { - client.get {} - } + val response = client.get {} + assertEquals(HttpStatusCode.OK, response.status) } } }