У меня проблема: когда мой код выдает несколько исключений в сопрограмме fn (в фоновом режиме), тогда основное приложение создает sh перед выполнением блока catch в фоновом режиме, но после этого выполняет блок catch. Как это можно исправить? Код работает нормально, если выбрасывает ошибку 1, но cra sh, если выдает многократную ошибку.
Ожидание: перехват первой ошибки и остановка выполнения в runBlocking без cra sh основное приложение.
Сообщение об ошибке:
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-8
Process: ..., PID: 9260
RuntimeException: my error
at MyBackgroundService ...
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:234)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)
Следующий код является очень упрощенной версией моего кода, которая представляла, как выглядит мой структурированный параллелизм:
class MyBackgroundService : IntentService("..."), CoroutineScope {
private var cJob: Job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + cJob
override fun onHandleIntent(intent: Intent?) {
/*...*/
try {
runBlocking {
fn1();
fn2();
}
} catch(e: RuntimeException) {
//before execution reach this the main app crashed with my custom error
//after that the app execute the catch block code and other coroutine fn still running in fn2
}
}
private suspend fun fn1() {
withContext(coroutineContext) {
/*...*/
}
}
private suspend fun fn2() {
withContext(coroutineContext) {
/*...*/
fn3()
/*other similar fn calls*/
/*after throw exception in fn3 the other coroutine functions still running */
}
}
private suspend fun fn3() {
launch {
fn4()
}
}
private suspend fun fn4() {
coroutineScope {
launch {
/*...*/
fn5()
}
}
}
fun CoroutineScope.fn5() {
for (/*...*/) {
launch {
fn6()
}
}
}
private suspend fun fn6() {
coroutineScope {
launch {
/*...*/
if (/*..*/) {
throw RuntimeException("my error") //this called multiple time because of for
}
}
}
}
}