[vcs] Handle exceptions thrown in SingleTaskRunner

GitOrigin-RevId: 6ef2d4f180c33f76564d48ea44478cccd911c63e
This commit is contained in:
Ilia.Shulgin
2025-10-09 20:57:35 +00:00
committed by intellij-monorepo-bot
parent 48e642dd96
commit 44cf8223ef
2 changed files with 30 additions and 1 deletions
@@ -2,6 +2,7 @@
package com.intellij.platform.vcs.impl.shared
import com.intellij.openapi.diagnostic.debug
import com.intellij.openapi.diagnostic.getOrHandleException
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.checkCanceled
import kotlinx.coroutines.*
@@ -37,7 +38,9 @@ class SingleTaskRunner(
busy.value = true
requested.value = false
checkCanceled()
task()
runCatching {
task()
}.getOrHandleException { LOG.error("Task failed", it) }
busy.value = false
}
}
@@ -3,6 +3,7 @@ package com.intellij.vcsUtil
import com.intellij.platform.util.coroutines.childScope
import com.intellij.platform.vcs.impl.shared.SingleTaskRunner
import com.intellij.testFramework.LoggedErrorProcessor
import com.intellij.testFramework.common.timeoutRunBlocking
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.TimeoutCancellationException
@@ -84,6 +85,31 @@ internal class SingleTaskRunnerTest {
}
}
@Test
fun `test thrown exception doesn't prevent further execution`() =
LoggedErrorProcessor.executeWith<IllegalStateException>(allowLoggedError()) {
timeoutRunBlocking {
var counter = 0
withRunner({
counter++
error("Test exception")
}) {
start()
request()
awaitNotBusy()
assertEquals(1, counter)
request()
awaitNotBusy()
assertEquals(2, counter)
}
}
}
private fun allowLoggedError() = object : LoggedErrorProcessor() {
override fun processError(category: String, message: String, details: Array<out String>, t: Throwable?): Set<Action> =
if (message.contains("Task failed")) Action.NONE else Action.ALL
}
private inline fun CoroutineScope.withRunner(
noinline task: suspend () -> Unit,
delay: Duration = Duration.Companion.ZERO,