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

myanmarking

05/21/2020, 9:58 AM
"Invokes the given action when the given flow is completed or cancelled, passing the cancellation exception or failure as cause parameter of action" -> Can some1 explain this documentation for flow.onComplete for me. I don't understand the last part "or failure as cause parameter of action", since an uncaught exception abort the stream. What is this failure refering to ?
For example:
Copy code
@Test
    fun `flow test`() = runBlockingTest{
        Assert.assertEquals(
            flow<Int>{
                throw IllegalStateException()
            }
                .map { 1 }
                .onCompletion { 2 }
                .toList(),
            listOf(2)
        )
    }

    @Test
    fun `flow test2`() = runBlockingTest{
        Assert.assertEquals(
            flow<Int>{
                throw IllegalStateException()
            }
                .catch {  }
                .map { 1 }
                .onCompletion { if(it != null) emit(2) }
                .toList(),
            listOf<Int>()
        )
    }
The first test crashes, the second test passes. So in what scenario does onComplete emits any exception other than cancellation ?
j

julian

05/23/2020, 3:06 AM
@myanmarking I haven't used Flows. But from reading the
onCompletion
docs,
onCompletion
doesn't emit an exception. The docs are just saying that the upstream exception (failure) gets passed as the
cause
argument of the
action
(lambda) argument that you provide to
onCompletion
.
onCompletion
behaves like
finally
, so the first test still crashes even with
onCompletion
applied. Furthermore, flow expects
action
to return
Unit
. So it doesn't matter that you have
2
in the lambda:
{ 2 }
. That has no effect. You'd need to
emit
to have an effect.
The second test doesn't
map
to
1
because you
emit
nothing in the
catch
lambda. In other words, the flow to this point is empty. So nothing to map. And
2
isn't emitted because the value of
it
in the
onCompletion
action
lambda is the upstream exception:
if(it != null) emit(2) }
. The upstream exception isn't null, so
emit(2)
isn't executed. So the list is empty. So the test passes.
That's how it all looks to me.
2 Views