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

vngantk

09/11/2019, 8:06 AM
Can anyone tell me what the expected behaviour of the following code is:
Copy code
fun main() = runBlocking {
    val job = Job()
    launch {
        delay(1000)
        job.completeExceptionally(IllegalStateException("Failed"))
    }
    try {
        job.join()
        println("foo")
    } catch (e: Exception) {
        println("bar")
        e.printStackTrace()
    }
}
d

Dico

09/11/2019, 8:09 AM
It prints foo
v

vngantk

09/11/2019, 8:11 AM
Why? I expect that the IllegalStateException would be caught and print "bar" and the stack trace.
d

Dico

09/11/2019, 8:12 AM
I'm pretty sure join just waits until the job completes, if it's not already completed.
The exception never gets thrown
await
from deferred will throw the exception though
v

vngantk

09/11/2019, 8:16 AM
So, the behaviour is not orthogonal
What if I do this:
Copy code
fun main() = runBlocking {
    val job = launch {
        delay(1000)
        throw IllegalStateException("Failed")
    }
    try {
        job.join()
        println("foo")
    } catch (e: Exception) {
        println("bar")
        e.printStackTrace()
    }
}
I have checked that for this case, the exception is thrown.
The Job() method returns a CompletableJob object which implements the Job interface, and so the behaviour of the join() method of a CompletableJob should be the same as we would expect from a normal Job object.
I am asking if this behaviour of the join() method of CompletableJob is implemented incorrectly or it is the correct behaviour intended by its author?
d

Dico

09/12/2019, 8:07 AM
Are you sure it's not just the default exception handler printing the stack trace?
Oh, I read your issue
As per documentation,
join
doesn't throw
It just awaits completion for any reason.
await
is a different function. Its behaviour is not tied.
b

bdawg.io

09/12/2019, 4:28 PM
This snippet on the other-hand will print
bar
Copy code
fun main() = runBlocking {
    val deferred = async {
        delay(1000)
        throw IllegalStateException("Failed")
    }
    try {
        deferred.await()
        println("foo")
    } catch (e: Exception) {
        println("bar")
        e.printStackTrace()
    }
}
4 Views