in kotlin-js how do i launch a coroutine from norm...
# coroutines
n
in kotlin-js how do i launch a coroutine from normal code without using GlobalScope ? using that exceptions get lost apparently ? is there a better thing ?
e
You can add your own
CoroutineExceptionHandler
to the
GlobalScope
or just catch your exceptions in the coroutines you launch.
But what do you mean “lost”? They should be delivered to the default exception handler, so on backend that would mean they get printed to console and on Android it means they should get logged and would crash your app. They should not be “lost”. Can you show how that is happening for you?
n
i guess i never installed a default exception handler, i am on jvm and javascript (browser), been too long since i did deep dive into coroutines, so i ask stupid questions
https://kotlinlang.org/docs/reference/coroutines/exception-handling.html#coroutineexceptionhandler this only talks about using ServiceLoader on jvm to install the
global exception handler
does that mean it is not possible for kotlin-js ?
f
@elizarov If you do something like this you will get no exception
Copy code
fun errorer() {
    GlobalScope.launch {
        error("asdf")
    }
}
fun main() {
    errorer()
}
This does error
Copy code
suspend fun errorer() = coroutineScope {
    launch {
        error("asdf")
    }
}

suspend fun main() {
    errorer()
}
d
@Fudge because the global scope threads are daemon threads. You have to delay program exit.
f
yeah I've just tried that and you are right
The difference will be the way exceptions are caught then, if you do this the exception will be caught:
Copy code
suspend fun errorer() = coroutineScope {
    launch {
        error("asdf")
    }
}

suspend fun main() {
    try {
        errorer()
    } catch (e: Exception) {
        println("Caught")
    }
    Thread.sleep(1000)
}
If you do this the exception won't be caught
Copy code
fun errorer() {
    GlobalScope.launch {
        error("asdf")
    }
}

fun main() {
    try {
        errorer()
    } catch (e: Exception) {
        println("Caught")
    }
    Thread.sleep(1000)
}
and in JS if there's no exception handler, in the former case if there is no try/catch it will error anyway because it will travel up the stack normally, and if you use GlobalScope it will silently fail. That's my theory, feel free to correct me.
n
i would like to install a default exception handler in js .. first thing is the main function can i do that ? because i am surely gonna forget to pass the handler in at least a few places and be confused for a whole afternoon
e
Copy code
val myScope = GlobalScope + CoroutineExceptionHandler { ... }
then use
myScope.launch { ... }
Search/Replace
GlobalScope
usage across your project with
myScope
.
There is a default handler on JS, too. It does
console.error(exception)
. So it should not be “lost” either.