Hi, I'm new to kotlin coroutines and couldn't figure out from the docs if the following is expected and if there is some other way to set a default uncaught exception handler: my problem is that in this example
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.swing.Swing
import java.awt.BorderLayout
import java.lang.Exception
import javax.swing.JButton
import javax.swing.JFrame
import javax.swing.WindowConstants
fun main(args: Array<String>) {
Thread.setDefaultUncaughtExceptionHandler { thread: Thread, throwable: Throwable ->
println("Uncaught throwable in thread ${thread.name}")
throwable.printStackTrace()
}
val btn = JButton("Hello")
btn.addActionListener {
async(Swing) {
throw Exception("World!")
}
}
val frame = JFrame()
frame.defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
frame.add(btn, BorderLayout.CENTER)
frame.pack()
frame.isVisible = true
}
The default thread uncaught exception handler is not being called.
Looks like you have to implement CoroutineExceptionHandler
private class UncaughtCoRoutineExceptionHandler :
CoroutineExceptionHandler, AbstractCoroutineContextElement(CoroutineExceptionHandler.Key) {
override fun handleException(context: CoroutineContext, exception: Throwable) {
println("handled")
}
}
private fun singleThread(name: String): CoroutineContext {
return newSingleThreadContext(name).plus(UncaughtCoRoutineExceptionHandler())
}
fun main(args: Array<String>) = runBlocking<Unit>(CommonPool) {
launch(singleThread("handler")) {
throw RuntimeException()
}
delay(1, TimeUnit.SECONDS)
}
The async function returns a future called Deferred: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/async.html
Just like with any other future-style or async functions in other languages, this future contains the result of the execution or the corresponding exception that happened during exception.
You code ignores the result of the async function in your code, thus the exception just sits there. If you want exception to be propagated to uncaught exception handler, then you should use launch instead of async:
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/launch.html
I see, thanks!
Most helpful comment
Looks like you have to implement CoroutineExceptionHandler