-
Notifications
You must be signed in to change notification settings - Fork 24
Exception handling in launch
Devrath edited this page Jan 16, 2024
·
7 revisions
- Entire Program crashes with the exception
- Also note Exception is propagated from children to parent
- Parent invokeOnCompletion is invoked but with an exception
- Then after Child-1 invokeOnCompletion is invoked but with an exception
- But Child-2 invokeOnCompletion is not invoked since exception was thrown here but crash log is printed
Parent throws exception Parent job is Cancelling
Child-1 throws exception Parent job is Cancelling
FATAL EXCEPTION: DefaultDispatcher-worker-3 java.lang.RuntimeException: Child-2 throws exception
class UsingLaunchExceptionHandleDemoVm @Inject constructor( ) : ViewModel() {
private val scopeJob = Job()
private val ourScope = CoroutineScope(scopeJob + Dispatchers.Default)
fun demo() {
ourScope.launch(CoroutineName("Parent")) {
try {
ourScope.launch(CoroutineName("Child-1")) {
try {
delay(10000)
}catch (ex : Exception){
println("Child-1 throws exception(Normal catch) ${ex.localizedMessage}")
}
}.invokeOnCompletion { throwable ->
if(throwable!=null){
// Exception thrown
println("Child-1 throws exception ${throwable.localizedMessage}")
}else{
// Normal completion of coroutine
println("Child-1 is complete")
}
}
ourScope.launch(CoroutineName("Child-2")) {
throw RuntimeException("Child-2 throws exception")
}.invokeOnCompletion{ throwable ->
if(throwable!=null){
// Exception thrown
println("Child-1 throws exception ${throwable.localizedMessage}")
}else{
// Normal completion of coroutine
println("Child-2 is complete")
}
}
}catch (ex : Exception){
println("Parent throws exception(Normal catch) ${ex.localizedMessage}")
}
// Outer delay
delay(15000)
}.invokeOnCompletion{ throwable ->
if(throwable!=null){
// Exception thrown
println("Parent throws exception ${throwable.localizedMessage}")
}else{
// Normal completion of coroutine
println("Parent is complete")
}
}
}
fun rootCancel() {
scopeJob?.cancel()
}
}
- Note that even though
Child-2
throws exception, Since its caught, it will complete
Child-2 throws exception(Normal catch) Child-2 throws exception
Child-2 is complete
Child-1 is complete
Parent is complete
class UsingLaunchExceptionHandleDemoVm @Inject constructor( ) : ViewModel() {
private val scopeJob = Job()
private val ourScope = CoroutineScope(scopeJob + Dispatchers.Default)
// <-----------------------> Catch locally using try catch <------------->
fun demo2() {
ourScope.launch(CoroutineName("Parent")) {
try {
ourScope.launch(CoroutineName("Child-1")) {
try {
delay(10000)
}catch (ex : Exception){
println("Child-1 throws exception(Normal catch) ${ex.localizedMessage}")
}
}.invokeOnCompletion { throwable ->
if(throwable!=null){
// Exception thrown
println("Child-1 throws exception ${throwable.localizedMessage}")
}else{
// Normal completion of coroutine
println("Child-1 is complete")
}
}
ourScope.launch(CoroutineName("Child-2")) {
try {
throw RuntimeException("Child-2 throws exception")
delay(10000)
}catch (ex : Exception){
println("Child-2 throws exception(Normal catch) ${ex.localizedMessage}")
}
}.invokeOnCompletion{ throwable ->
if(throwable!=null){
// Exception thrown
println("Child-1 throws exception ${throwable.localizedMessage}")
}else{
// Normal completion of coroutine
println("Child-2 is complete")
}
}
}catch (ex : Exception){
println("Parent throws exception(Normal catch) ${ex.localizedMessage}")
}
// Outer delay
delay(15000)
}.invokeOnCompletion{ throwable ->
if(throwable!=null){
// Exception thrown
println("Parent throws exception ${throwable.localizedMessage}")
}else{
// Normal completion of coroutine
println("Parent is complete")
}
}
}
// <-----------------------> Catch locally using try catch <------------->
}