Any expert on coroutines could help me here Hi guy...
# coroutines
b
Any expert on coroutines could help me here Hi guys i have a doubt?
Copy code
fun test() {
    coroutineScope.launch {
        launch {
            makeApiCall()
            throwException()
        }
        launch {
            makeApiCall2()
        }
    }
}

fun throwException() {
    throw CancellationException("Error")
}

suspend fun makeApiCall() {
    delay(2.seconds)
    Log.d(TAG, "Successful Api Call")
}


suspend fun makeApiCall2() {
    delay(5.seconds)
    Log.d(TAG, "Successful Api Call 2")
}
What will be the output the shouldn't the second api call fail cos it is with 5 sec delay but till that time the coroutine should cancel as the exception is uncaught and it should propagate to parent right?
K 1
s
Depends on the
coroutineScope
. If its job is a SupervisorJob, the other children won't be cancelled.
b
it is
Copy code
val coroutineScope = CoroutineScope(Dispatchers.Main)
so it should cancel right?
but it is now @streetsofboston
s
It should, since by default a 'plain' Job is used when constructing a CoroutineScope.... What happens if you throw a regular Throwable (not a CancellationException)?
b
Aha still wrong let me show you another thing then
Copy code
val TAG = "CoroutinesTest"
val coroutineScope = CoroutineScope(Dispatchers.Main)
val supervisorScope = CoroutineScope(Dispatchers.Main + SupervisorJob())

val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
    Log.d(TAG, "Caught Exception: $throwable")
}

class CoroutinesActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Box(Modifier.fillMaxSize())
        }

        test()
    }
}


fun test() {
    supervisorScope.launch(exceptionHandler) {
        launch {
            makeApiCall()
            throwException()
        }
        launch {
            makeApiCall2()
        }
    }
}

fun throwException() {
    throw Exception("Error")
}

suspend fun makeApiCall() {
    delay(2.seconds)
    Log.d(TAG, "Successful Api Call")
}


suspend fun makeApiCall2() {
    delay(5.seconds)
    Log.d(TAG, "Successful Api Call 2")
}
Now this is the code snippet
now what should be the result? here i am using supervisorjob added as context
i am testing things as much as possible but i cant find the actual help of Supervisor Scope as it is giving me same results as normal scope
m
You should be using
supervisorScope { ... }
rather than what you have.
b
Whats the difference ? @muliyul
j
throwing CancellationException doesn't cancel things
that's the exception that is thrown at you when the job is canceled
If you want api call 2 to be independent of api call 1, they need to be in separate children of the supervisor scope
Copy code
supervisorScope.launch(exceptionHandler) {
        makeApiCall()
        throwException()
    }
    supervisorScope.launch(exceptionHandler) {
        makeApiCall2()
    }
m
Revisiting this, @JP Sugarbroad is right. You are launching both calls from a child (notice singular) coroutine. Use supervisorScope.launch for each and you should be good to go.
b
@JP Sugarbroad @muliyul dont think of it as APi call as we know the cancelaation Exception propagates right although there is single launch block on top but it has 2 childs right so if one child gets cancelled it propagates to parent right and if parent fails then it fails all childs if thet is not a Supervisor JOb ? isnt this statement right ?
j
Yes, so you have:
Copy code
Job 1 (supervisor)
\- job 2 (launch with exception handler)
   \- job 3 (launch) 
   \- job 4 (launch)
When job 3 throws, job 2 cancels job 4 and propagates the exception up. Job 1 catches it and would not cancel any other children, but it doesn't have any anyway.
👍 1
b
@JP Sugarbroad yes i understood actually i was thinking if i launch a coroutine with SupervisorJob and have multiple coroutines inside them i thought all of them would be supervisor Jobs but it is not the case plus i got to know CancellationExceptions do not propagate to parent i was a but confused over there
👍 1