https://kotlinlang.org logo
Title
d

dave08

04/13/2023, 12:05 PM
Anyone knows how the top-level
fold
handles
TimeoutCancellationException
s? It seems like they're rethrown... but in Ktor, I'd like to use it to return some kind of timeout response to the client... (I suspect that Ktor just hangs w/o some kind of timeout in certain situations...)
Would this do it:
private suspend inline fun KtorCtx.respond(
    statusCode: HttpStatusCode,
    noinline action: suspend Raise<ErrorContext>.() -> String
): Unit = fold(
    {
        withTimeout(5.seconds) {
            action()
        }
    },
    { 
        if (it is TimeoutCancellationException)
            call.respond(RequestTimeout)
        else
            throw it
    },
    { error ->
        val jsonError = Json.encodeToString(error)
        call.respond(BadRequest, error.toString())
        application.log.error(jsonError)
    }) { a ->
        call.respondText(a, ContentType.Application.Json, statusCode)
    }
?
s

stojan

04/13/2023, 12:12 PM
you could use
withTimeoutOrNull
d

dave08

04/13/2023, 12:17 PM
... not such a nice hack there with
?: ""
private suspend inline fun KtorCtx.respond(
    statusCode: HttpStatusCode,
    noinline action: suspend Raise<ErrorContext>.() -> String
): Unit = fold(
    {
        withTimeoutOrNull(5.seconds) {
            action()
        }?.also { call.respond(RequestTimeout) } ?: ""
    },
    { error ->
        val jsonError = Json.encodeToString(error)
        call.respond(BadRequest, error.toString())
        application.log.error(jsonError)
    }) { a ->
        call.respondText(a, ContentType.Application.Json, statusCode)
    }
Otherwise
a
isn't a type
respondText
accepts...
s

simon.vergauwen

04/13/2023, 1:37 PM
This is because
TimeoutCancellation
inherits from
CancellationException
. There is some discussion on KotlinX Coroutines to change this, but it’s a binar breaking change. They might change this is 2.0, but you can use
withTimeoutOrNull
& custom exception or Java’s
TimeoutException