PHaroZ
04/12/2022, 5:13 PMHttpTimeout
feature ; I try to figure out were I can catch the HttpRequestTimeoutException
thrown but I don't find any clean and generic solution.
Here is my config :
val engine = TODO("CIO.create() or MockEngine")
val ktorBaseClient = HttpClient(engine) {
install(HttpTimeout)
}
val ktorClient = ktorBaseClient.config {
HttpResponseValidator {
handleResponseException { t ->
when (t) {
// -----> next line works with MockEngine but not with CIO.create()
is HttpRequestTimeoutException -> throw MyCustomException()
else -> throw t
}
}
validateResponse { response ->
// it doesn't seem do by the right place to catch HttpRequestTimeoutException
...
}
}
}
ktorClient.get("some_uri") {
timeout { requestTimeoutMillis = 1.seconds.inWholeMilliseconds }
}
Note that to simulate a timeout via the MockEngine I do something like
MockEngine {
delay(2.seconds.inWholeMilliseconds)
throw IllegalStateException("should never be called")
}
and it works, it throws a MyCustomException
; but this is not the case in production code, with the CIO engine.
Does someone have any advice or example ? thx for your help.PHaroZ
04/12/2022, 5:16 PMCaused by: io.ktor.client.features.HttpRequestTimeoutException: Request timeout has expired [url=<http://XXXXXX>, request_timeout=15000 ms]
at io.ktor.client.features.HttpTimeout$Feature$install$1$1$killer$1.invokeSuspend(HttpTimeout.kt:149)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Aleksei Tirman [JB]
04/12/2022, 8:56 PMtry/catch
to catch the HttpRequestTimeoutException
. Could you please describe what problem are you trying to solve?PHaroZ
04/13/2022, 6:13 AMtry/catch
work fine, however I have to implement this logic in each call. I was looking for something more generic if it exists.
Thx for your help 🙂Aleksei Tirman [JB]
04/13/2022, 11:36 AMexecutionContext
of a request is cancelled with the HttpRequestTimeoutException
so you can add a handler that will be called when request’s job is completed (with an exception or not). Here is an example:
val client = HttpClient(Apache) {
install(HttpTimeout) {
requestTimeoutMillis = 1
}
}
client.requestPipeline.intercept(HttpRequestPipeline.Before) {
context.executionContext.invokeOnCompletion { cause ->
if (cause is HttpRequestTimeoutException) {
println("Warning")
}
}
}
client.get<String>("<https://example.com>")