simon.vergauwen
01/21/2019, 1:12 PMDeferred<A>
? I was expecting to be able to define a handleErrorWith
operator that wraps an existing Deferred
to recover from errors but the program results in the original error.Allan Wang
01/21/2019, 2:25 PMlouiscad
01/21/2019, 3:03 PMcoroutineScope { ... }
, and catch exceptions outside of it for this to work properly. That is structured concurrency.
Also, most of the time, you won't need Deferred
nor async
and await
because suspend fun
, withContext
and launch
satisfy most use cases.simon.vergauwen
01/21/2019, 3:11 PMDeferred
with coroutineScope
can prevent this?Deferred
specific implementationAllan Wang
01/21/2019, 3:14 PMhandleErrorWith
create the deferred executions? Otherwise I’m not sure there’s anything you can do to stop parent cancellation unless the deferred creator implements itsimon.vergauwen
01/21/2019, 3:15 PMDeferred
there is no way to know what code is underneath.louiscad
01/21/2019, 3:19 PMasync
calls more specifically.simon.vergauwen
01/21/2019, 3:19 PMDeferred
I am wrapping.fun <A> CoroutineScope.handleErrorWith(fa: Deferred<A>, f: (Throwable) -> Deferred<A>): Deferred<A> =
async(start = CoroutineStart.LAZY) {
try {
coroutineScope {
fa.await()
}
} catch (e: Throwable) {
f(e).await()
}
}
Allan Wang
01/21/2019, 3:23 PMSupervisorJob
to your caller context (which you can’t control)import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.plus
import kotlinx.coroutines.runBlocking
import kotlin.test.Test
class Test {
fun <A> CoroutineScope.handleErrorWith(fa: Deferred<A>, f: (Throwable) -> Deferred<A>): Deferred<A> =
async(start = CoroutineStart.LAZY) {
try {
fa.await()
} catch (e: Throwable) {
f(e).await()
}
}
@Test
fun t() = runBlocking {
val result =
with(CoroutineScope(Dispatchers.Default) + SupervisorJob()) {
handleErrorWith(async(start = CoroutineStart.LAZY) {
throw RuntimeException("Boom!")
}) {
async { it.message }
}
}
val r = result.await() //threw RuntimeException("Boom!") but expected String of value "Boom!"
println(r)
}
}
simon.vergauwen
01/21/2019, 3:42 PM