Nino
02/05/2024, 9:04 AMrunCatching
, which isn't great with coroutines, and I want to let errors through.
• I explored catching Exception
but that still wouldn't work with coroutines (catching CancellationException
isn't a good idea)
• I explored catching as many exceptions I could find in the Ktor source code, but what if I miss one ?
This looks way to hacky, I must be missing something ?Sam
02/05/2024, 9:11 AMException
safely you can do this:
try {
doStuff()
} catch(e: Exception) {
currentCoroutineContext().ensureActive() // makes cancellation work correctly
handleError(e)
}
Or, if you have #arrow, you could use its NonFatal
function:
try {
doStuff()
} catch(t: Throwable) {
if (NonFatal(t)) handleError(t) else throw t
}
Sam
02/05/2024, 9:13 AMNino
02/05/2024, 9:14 AMensureActive
!Nino
02/05/2024, 9:25 AMprivate suspend fun doStuff(payload: FooPayload) {
val foo: String? = client.safeGet("foo") {
contentType(ContentType.Application.Json)
}
println(foo)
val bar: String? = client.safePost("bar") {
contentType(ContentType.Application.Json)
setBody(payload)
}
println(bar)
}
private suspend inline fun <reified T> HttpClient.safeGet(url: String, block: HttpRequestBuilder.() -> Unit): T? =
safeRequest(url) {
method = HttpMethod.Get
block()
}
private suspend inline fun <reified T> HttpClient.safePost(url: String, block: HttpRequestBuilder.() -> Unit): T? =
safeRequest(url) {
method = <http://HttpMethod.Post|HttpMethod.Post>
block()
}
private suspend inline fun <reified T> HttpClient.safeRequest(url: String, block: HttpRequestBuilder.() -> Unit): T? =
try {
request {
url(url)
block()
}.body()
} catch (e: Exception) {
currentCoroutineContext().ensureActive()
e.printStackTrace()
null
}