Anyone knows how the top-level `fold` handles `Ti...
# arrow
d
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:
Copy code
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
you could use
withTimeoutOrNull
d
... not such a nice hack there with
?: ""
Copy code
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
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