Created
September 27, 2022 10:08
-
-
Save Audhil/7732b5e52020627e0df833bf1faae3f5 to your computer and use it in GitHub Desktop.
Exceptions handling in Kotlin Coroutines : https://youtu.be/VWlwkqmTLHc?list=PLQkwcJG4YTCQcFEPuYGuv54nYai_lwil_
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://youtu.be/VWlwkqmTLHc?list=PLQkwcJG4YTCQcFEPuYGuv54nYai_lwil_ | |
// USING TRY-CATCH FOR EXCEPTION HANDLING | |
// wrong | |
lifecycleScope.launch { | |
try { | |
launch { | |
throw Exception("failed") | |
} | |
} catch (e: Exception) { | |
} | |
} | |
// ok-ish | |
lifecycleScope.launch { | |
try { | |
launch { | |
try { | |
throw Exception("failed") | |
} catch (e: Exception) { | |
} | |
} | |
} catch (e: Exception) { | |
} | |
} | |
// wrong - crash, since exceptions are propagated up to launch{} we don't have try catch | |
lifecycleScope.launch { | |
val def = lifecycleScope.async { | |
delay(500L) | |
throw Exception("crash!") | |
"Jack and jill" | |
} | |
} | |
// wrong - won't crash | |
val deff = lifecycleScope.async { | |
val def = lifecycleScope.async { | |
delay(500L) | |
throw Exception("crash!") | |
"Jack and jill" | |
} | |
} | |
lifecycleScope.launch { | |
deff.await() // this line will make the app crash | |
} | |
// ok-ish - this will prevent from crash | |
lifecycleScope.launch { | |
try { | |
deff.await() | |
} catch (e: Exception) { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://youtu.be/VWlwkqmTLHc?list=PLQkwcJG4YTCQcFEPuYGuv54nYai_lwil_ | |
// USING EXCEPTION HANDLER | |
// this handler will not get executed for CancellationException, since those exceptions are handled by default. | |
// this will be executed only for uncaught exceptions | |
val execeptionHandler = CoroutineExceptionHandler { context, throwable -> | |
println("yup: caught: exception: $throwable") | |
} | |
lifecycleScope.launch(execeptionHandler) { | |
launch { | |
throw Exception("hi hi exception!") | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CoroutineScope(Dispatchers.Main).launch { | |
launch { | |
delay(3000L) | |
throw Exception("coroutine 1 failed") // crashes app | |
} | |
launch { | |
delay(3000L) | |
println("coroutine 2 finished") // this line is not executed, since scope cancelled other coroutines, when it faces a exception from one of the coroutine | |
} | |
} | |
// with exception handler | |
// 2022-09-27 15:12:43.572 11123-11123/com.example.dummy I/System.out: yup: 2nd caught: exception: java.lang.Exception: coroutine 1 failed | |
val exHandler = CoroutineExceptionHandler { context, throwable -> | |
println("yup: 2nd caught: exception: $throwable") | |
} | |
CoroutineScope(Dispatchers.Main + exHandler).launch { | |
launch { | |
delay(3000L) | |
throw Exception("coroutine 1 failed") | |
} | |
launch { | |
delay(3000L) | |
println("coroutine 2 finished") // still this coroutine is cancelled, it'll not print | |
} | |
} | |
// the solution | |
// 2022-09-27 15:17:30.479 11197-11197/com.example.dummy I/System.out: yup: 3nd caught: exception: java.lang.Exception: coroutine 1 failed | |
// 2022-09-27 15:17:30.481 11197-11197/com.example.dummy I/System.out: coroutine 2 finished | |
val exHandler2 = CoroutineExceptionHandler { context, throwable -> | |
println("yup: 3nd caught: exception: $throwable") | |
} | |
CoroutineScope(Dispatchers.Main + exHandler2).launch { | |
supervisorScope { | |
launch { | |
delay(3000L) | |
throw Exception("coroutine 1 failed") | |
} | |
launch { | |
delay(3000L) | |
println("coroutine 2 finished") | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ANOTHER ERROR - https://youtu.be/VWlwkqmTLHc?list=PLQkwcJG4YTCQcFEPuYGuv54nYai_lwil_&t=1129 | |
// eventhough we cancelled the coroutine, it is still executing the statements; the reason is cancellationException is eaten by catch{} | |
// 2022-09-27 15:23:40.219 13354-13354/com.example.dummy W/System.err: kotlinx.coroutines.JobCancellationException: StandaloneCoroutine was cancelled; job=StandaloneCoroutine{Cancelling}@2e5ac99 | |
// 2022-09-27 15:23:40.219 13354-13354/com.example.dummy I/System.out: coroutine is finished | |
lifecycleScope.launch { | |
val job = launch { | |
try { | |
delay(500L) | |
} catch (e: Exception) { | |
e.printStackTrace() | |
} | |
println("coroutine is finished") | |
} | |
delay(300L) | |
job.cancel() | |
} | |
// solution: option 1: catch specific exceptions | |
// 2022-09-27 15:32:15.565 14225-14225/com.example.dummy I/System.out: HHHH : 2nd before exception: Log | |
lifecycleScope.launch { | |
val job = launch { | |
try { | |
println("HHHH : 2nd before exception: Log") | |
delay(500L) | |
} catch (e: NullPointerException) { | |
e.printStackTrace() | |
} | |
println("HHHH : 2nd after exception: Log") | |
println("HHHH : 2nd time coroutine is finished") | |
} | |
delay(300L) | |
job.cancel() | |
} | |
// solution: option 2: re throw the exception | |
// 2022-09-27 15:32:15.568 14225-14225/com.example.dummy I/System.out: HHHH : 3rd before exception: Log | |
lifecycleScope.launch { | |
val job = launch { | |
try { | |
println("HHHH : 3rd before exception: Log") | |
delay(500L) | |
} catch (e: Exception) { | |
if (e is CancellationException) | |
throw e | |
e.printStackTrace() | |
} | |
println("HHHH : 3rd after exception: Log") | |
println("HHHH : 3rd time coroutine is finished") | |
} | |
delay(300L) | |
job.cancel() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment