Skip to content

Instantly share code, notes, and snippets.

@Audhil
Created September 27, 2022 10:08
Show Gist options
  • Save Audhil/7732b5e52020627e0df833bf1faae3f5 to your computer and use it in GitHub Desktop.
Save Audhil/7732b5e52020627e0df833bf1faae3f5 to your computer and use it in GitHub Desktop.
// 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) {
}
}
// 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!")
}
}
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")
}
}
}
// 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