https://kotlinlang.org logo
#coroutines
Title
# coroutines
a

Allan Wang

01/17/2019, 6:58 AM
I have the following block of code:
Copy code
scope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
    val result = runCatching {
        fetcher(key)
    }
    receiverChannel.send(key to result)
}
The scope is currently
GlobalScope
and
fetcher
is a suspended function (that just returns an exception) Even with runcatching, I’m getting
Copy code
FATAL EXCEPTION: DefaultDispatcher-worker-4
    ...
    java.lang.RuntimeException: Test
Is there something else I’m missing? Do I need to add a new scope here?
o

octylFractal

01/17/2019, 6:59 AM
what's the stacktrace look like?
a

Allan Wang

01/17/2019, 7:07 AM
This is how it runs on a clean test, which just waits on a single completable that should return the fetched result:
Copy code
Exception in thread "DefaultDispatcher-worker-1 @coroutine#3" java.lang.RuntimeException: Crash key
	at com.pitchedapps.frost.kotlin.FlyweightTest$before$1.invoke(FlyweightTest.kt:51)
	at com.pitchedapps.frost.kotlin.FlyweightTest$before$1.invoke(FlyweightTest.kt:32)
	at com.pitchedapps.frost.kotlin.Flyweight$fulfill$1.invokeSuspend(Flyweight.kt:126)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
	at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)

java.lang.RuntimeException: Crash key

	at com.pitchedapps.frost.kotlin.FlyweightTest$before$1.invoke(FlyweightTest.kt:51)
	at com.pitchedapps.frost.kotlin.FlyweightTest$before$1.invoke(FlyweightTest.kt:32)
	at com.pitchedapps.frost.kotlin.Flyweight$fulfill$1.invokeSuspend(Flyweight.kt:126)
	at |b|b|b(Coroutine boundary.|b(|b)
	at kotlinx.coroutines.CompletableDeferredImpl.await(CompletableDeferred.kt:64)
	at com.pitchedapps.frost.kotlin.FlyweightTest$error$1.invokeSuspend(FlyweightTest.kt:102)
Caused by: java.lang.RuntimeException: Crash key
	at com.pitchedapps.frost.kotlin.FlyweightTest$before$1.invoke(FlyweightTest.kt:51)
	at com.pitchedapps.frost.kotlin.FlyweightTest$before$1.invoke(FlyweightTest.kt:32)
	at com.pitchedapps.frost.kotlin.Flyweight$fulfill$1.invokeSuspend(Flyweight.kt:126)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
	at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)
Not sure why it ends up being logged three times
Code: https://github.com/AllanWang/Frost-for-Facebook/blob/dev/app/src/main/kotlin/com/pitchedapps/frost/kotlin/Flyweight.kt Test:
Copy code
@Test
fun error() {
    runBlocking {
        flyweight.fetch(CRASH_KEY).await()
    }
}
I’m trying to debug something where the log seems to be erased due to coroutines, but I think it’s related to this problem here
o

octylFractal

01/17/2019, 7:24 AM
looks tricky, not sure why it's going wrong. I'd probably need to look at the class files 😐
a

Allan Wang

01/17/2019, 7:32 AM
The actual problem I have is way weirder. I have a suspend function that is called with an io dispatcher. I’m calling my flyweight, which doesn’t deal with the main thread at all, and then returning something. If the flyweight fails, I get a problem that I called an action without a looper, which in android implies that I called a ui action on a worker thread. However, if the flyweight succeeds, or if I replace the flyweight call with a
throw
, everything is fine. And given I have no line numbers for the error, and this only occurred when I switched from rx to coroutines, I know it’s something wrong with how I rewrote it
2 Views