I have code in Android as follow:
//use MainScope
private val scope = MainScope()
private fun test() {
scope.launch {
Log.d(TAG, "test: launch")
try {
val response: Deferred<String> = async {
Log.d(TAG, "test: in async block")
throw IllegalStateException("an IllegalStateException")
}
response.await()
} catch (e: Exception) {
Log.d(TAG, "test: error ${e.message}")
}
}
}
I use MainScope
to launch a coroutine and use async
to launch a child coroutine in it. When i use try/catch
to catch the exception of child coroutine , i failed and the application crashed. Could some one tell me why ?
Crash messages as follow:
D/AsyncExceptionTestActiv: test: launch
D/AsyncExceptionTestActiv: test: in async block
D/AsyncExceptionTestActiv: test: error an IllegalStateException
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.hm.dumingwei.kotlinandroid, PID: 18461
java.lang.IllegalStateException: an IllegalStateException
at com.hm.dumingwei.kotlinandroid.AsyncExceptionTestActivity$test$1$response$1.invokeSuspend(AsyncExceptionTestActivity.kt:61)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6517)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
The exception thrown inside nested coroutine is propagated to the parent coroutine unless you use a SupervisorJob
:
scope.launch {
Log.d(TAG, "test: launch")
try {
val response: Deferred<String> = async(SupervisorJob()) {
Log.d(TAG, "test: in async block")
throw IllegalStateException("an IllegalStateException")
}
response.await()
} catch (e: Exception) {
Log.d(TAG, "test: error ${e.message}")
}
}