[platform] IJPL-1039: extend ProcessCanceledException from CancellationException

GitOrigin-RevId: 8edd7e83dc7029225e6d98f538428d6d6acfcc50
This commit is contained in:
Konstantin Nisht
2024-04-12 15:40:32 +02:00
committed by intellij-monorepo-bot
parent 5fcb10fa31
commit 12e78f18d6
24 changed files with 71 additions and 58 deletions

View File

@@ -131,6 +131,9 @@ private fun <T> runBlockingCancellable(allowOrphan: Boolean, action: suspend Cor
@Suppress("RAW_RUN_BLOCKING") @Suppress("RAW_RUN_BLOCKING")
runBlocking(ctx + readActionContext(), action) runBlocking(ctx + readActionContext(), action)
} }
catch (pce: ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) { catch (ce: CancellationException) {
throw CeProcessCanceledException(ce) throw CeProcessCanceledException(ce)
} }
@@ -169,6 +172,9 @@ fun <T> indicatorRunBlockingCancellable(indicator: ProgressIndicator, action: su
@Suppress("RAW_RUN_BLOCKING") @Suppress("RAW_RUN_BLOCKING")
runBlocking(context + readActionContext(), action) runBlocking(context + readActionContext(), action)
} }
catch (pce: ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) { catch (ce: CancellationException) {
throw CeProcessCanceledException(ce) throw CeProcessCanceledException(ce)
} }
@@ -375,11 +381,15 @@ suspend fun <T> coroutineToIndicator(action: () -> T): T {
*/ */
@Internal @Internal
@RequiresBlockingContext @RequiresBlockingContext
@Throws(ProcessCanceledException::class)
fun <T> blockingContextToIndicator(action: () -> T): T { fun <T> blockingContextToIndicator(action: () -> T): T {
val ctx = currentThreadContext() val ctx = currentThreadContext()
return try { return try {
contextToIndicator(ctx, action) contextToIndicator(ctx, action)
} }
catch (pce : ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) { catch (ce: CancellationException) {
throw CeProcessCanceledException(ce) throw CeProcessCanceledException(ce)
} }

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.externalSystem.service.project.manage; package com.intellij.openapi.externalSystem.service.project.manage;
import com.intellij.concurrency.ConcurrentCollectionFactory; import com.intellij.concurrency.ConcurrentCollectionFactory;
@@ -21,7 +21,6 @@ import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalS
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.project.ProjectUtil;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
@@ -146,7 +145,7 @@ public final class ExternalProjectsDataStorage extends SimpleModificationTracker
} }
} }
} }
catch (ProcessCanceledException | CancellationException e) { catch (CancellationException e) {
throw e; throw e;
} }
catch (Throwable e) { catch (Throwable e) {

View File

@@ -417,7 +417,7 @@ final class PassExecutorService implements Disposable {
myPass.collectInformation(myUpdateProgress); myPass.collectInformation(myUpdateProgress);
} }
} }
catch (ProcessCanceledException | CancellationException e) { catch (CancellationException e) {
cancelled = true; cancelled = true;
throw e; throw e;
} }

View File

@@ -104,6 +104,9 @@ class IndexUpdateRunner(private val myFileBasedIndex: FileBasedIndexImpl,
@Suppress("RAW_RUN_BLOCKING") @Suppress("RAW_RUN_BLOCKING")
runBlocking(ctx + readActionContext(), action) runBlocking(ctx + readActionContext(), action)
} }
catch (pce : ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) { catch (ce: CancellationException) {
throw CeProcessCanceledException(ce) throw CeProcessCanceledException(ce)
} }

View File

@@ -323,7 +323,7 @@ public final class TreeState implements JDOMExternalizable {
try { try {
myPresentationData = readExternalPresentation(element); myPresentationData = readExternalPresentation(element);
} }
catch (ProcessCanceledException | CancellationException ignored) { catch (CancellationException ignored) {
} }
catch (Exception e) { catch (Exception e) {
LOG.warn("An error occurred while trying to read a cached tree presentation", e); LOG.warn("An error occurred while trying to read a cached tree presentation", e);

View File

@@ -611,6 +611,9 @@ internal class ActionUpdater @JvmOverloads constructor(
try { try {
return deferred.getCompleted() return deferred.getCompleted()
} }
catch (pce : ProcessCanceledException) {
throw pce
}
catch (ex: CancellationException) { catch (ex: CancellationException) {
throw CeProcessCanceledException(ex) throw CeProcessCanceledException(ex)
} }

View File

@@ -1238,6 +1238,9 @@ internal inline fun <R> runBlockingForActionExpand(context: CoroutineContext = E
@Suppress("RAW_RUN_BLOCKING") @Suppress("RAW_RUN_BLOCKING")
runBlocking(ctx + context + Context.current().asContextElement(), block) runBlocking(ctx + context + Context.current().asContextElement(), block)
} }
catch (pce : ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) { catch (ce: CancellationException) {
throw CeProcessCanceledException(ce) throw CeProcessCanceledException(ce)
} }

View File

@@ -522,7 +522,7 @@ public final class NonBlockingReadActionImpl<T> implements NonBlockingReadAction
} }
} }
} catch (ProcessCanceledException e) { } catch (ProcessCanceledException e) {
cancelJob(new PceCancellationException(e)); cancelJob(e);
throw e; throw e;
} }
finally { finally {
@@ -667,17 +667,6 @@ public final class NonBlockingReadActionImpl<T> implements NonBlockingReadAction
private void failJob(@NotNull Throwable reason) { private void failJob(@NotNull Throwable reason) {
Continuation<Unit> continuation = myChildContext.getContinuation(); Continuation<Unit> continuation = myChildContext.getContinuation();
if (continuation != null) { if (continuation != null) {
if (reason instanceof ProcessCanceledException e) {
Job job = myChildContext.getJob();
if (job != null) {
// Normally, any exception reported here goes directly to top-level `CoroutineExceptionHandlerImpl`.
// This is undesirable for PCE, which expresses cancellation, and not a fatal error.
// As a rule, PCE in continuation is handled in `runAsCoroutine`, but since we are opting for manual cancellation handling,
// we need to process PCE manually as well.
job.cancel(new PceCancellationException(e));
return;
}
}
continuation.resumeWith(new Result.Failure(reason)); continuation.resumeWith(new Result.Failure(reason));
} }
} }

View File

@@ -6,8 +6,6 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.ReadConstraint import com.intellij.openapi.application.ReadConstraint
import com.intellij.openapi.application.ex.ApplicationEx import com.intellij.openapi.application.ex.ApplicationEx
import com.intellij.openapi.progress.PceCancellationException
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.blockingContext import com.intellij.openapi.progress.blockingContext
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext

View File

@@ -548,7 +548,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
fileType = ApplicationManager.getApplication().instantiateClass(bean.implementationClass, bean.getPluginDescriptor()); fileType = ApplicationManager.getApplication().instantiateClass(bean.implementationClass, bean.getPluginDescriptor());
} }
} }
catch (ProcessCanceledException | CancellationException e) { catch (CancellationException e) {
throw e; throw e;
} }
catch (Exception e) { catch (Exception e) {

View File

@@ -12,10 +12,7 @@ import com.intellij.openapi.application.impl.RawSwingDispatcher
import com.intellij.openapi.application.impl.inModalContext import com.intellij.openapi.application.impl.inModalContext
import com.intellij.openapi.application.isModalAwareContext import com.intellij.openapi.application.isModalAwareContext
import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.CeProcessCanceledException import com.intellij.openapi.progress.*
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.TaskInfo
import com.intellij.openapi.progress.prepareThreadContext
import com.intellij.openapi.progress.util.* import com.intellij.openapi.progress.util.*
import com.intellij.openapi.progress.util.ProgressIndicatorWithDelayedPresentation.DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS import com.intellij.openapi.progress.util.ProgressIndicatorWithDelayedPresentation.DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
@@ -118,6 +115,9 @@ class PlatformTaskSupport(private val cs: CoroutineScope) : TaskSupport {
try { try {
scope.runWithModalProgressBlockingInternal(dispatcher = null, descriptor, action) scope.runWithModalProgressBlockingInternal(dispatcher = null, descriptor, action)
} }
catch (pce: ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) { catch (ce: CancellationException) {
throw CeProcessCanceledException(ce) throw CeProcessCanceledException(ce)
} }

View File

@@ -124,7 +124,7 @@ final class RefreshWorker {
processQueue(threadEvents); processQueue(threadEvents);
} }
catch (RefreshCancelledException ignored) { } catch (RefreshCancelledException ignored) { }
catch (ProcessCanceledException | CancellationException e) { catch (CancellationException e) {
myCancelled = true; myCancelled = true;
} }
catch (Throwable t) { catch (Throwable t) {

View File

@@ -2,10 +2,8 @@
package com.intellij.application package com.intellij.application
import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.util.registry.Registry
import com.intellij.testFramework.LightPlatformTestCase import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.testFramework.LoggedErrorProcessor import com.intellij.testFramework.LoggedErrorProcessor
import com.intellij.testFramework.assertInstanceOf
import com.intellij.util.getValue import com.intellij.util.getValue
import com.intellij.util.setValue import com.intellij.util.setValue
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -29,13 +27,7 @@ class PooledCoroutineContextTest : LightPlatformTestCase() {
@Test @Test
fun `do not log ProcessCanceledException`() { fun `do not log ProcessCanceledException`() {
val exception = ProcessCanceledException() val exception = ProcessCanceledException()
val logged = loggedErrorsAfterThrowingFromGlobalScope(exception) assertNull(loggedErrorsAfterThrowingFromGlobalScope(exception))
if (Registry.`is`("ide.log.coroutine.pce")) {
assertSame(exception, assertInstanceOf<IllegalStateException>(logged).cause)
}
else {
assertNull(logged)
}
} }
private fun loggedErrorsAfterThrowingFromGlobalScope(exception: Throwable): Throwable? = withNoopThreadUncaughtExceptionHandler { private fun loggedErrorsAfterThrowingFromGlobalScope(exception: Throwable): Throwable? = withNoopThreadUncaughtExceptionHandler {

View File

@@ -70,12 +70,12 @@ class CoroutineToIndicatorTest : CancellationTest() {
} }
private suspend inline fun testRunUnderIndicatorRethrow(t: ProcessCanceledException) { private suspend inline fun testRunUnderIndicatorRethrow(t: ProcessCanceledException) {
val thrown = assertThrows<PceCancellationException> { val thrown = assertThrows<ProcessCanceledException> {
coroutineToIndicator { coroutineToIndicator {
throw t throw t
} }
} }
assertSame(t, thrown.cause) assertSame(t, thrown)
} }
@Test @Test

View File

@@ -186,7 +186,7 @@ class RunBlockingCancellableTest : CancellationTest() {
private fun testRunBlockingCancellableRethrow() { private fun testRunBlockingCancellableRethrow() {
testRunBlockingCancellableRethrow(object : Throwable() {}) testRunBlockingCancellableRethrow(object : Throwable() {})
testRunBlockingCancellableRethrow(CancellationException()) // manual CE testRunBlockingCancellableRethrowPce(CancellationException()) // manual CE
testRunBlockingCancellableRethrow(ProcessCanceledException()) // manual PCE testRunBlockingCancellableRethrow(ProcessCanceledException()) // manual PCE
} }
@@ -199,7 +199,7 @@ class RunBlockingCancellableTest : CancellationTest() {
assertSame(t, thrown) assertSame(t, thrown)
} }
private fun testRunBlockingCancellableRethrow(t: CancellationException) { private fun testRunBlockingCancellableRethrowPce(t: CancellationException) {
val thrown = assertThrows<CeProcessCanceledException> { val thrown = assertThrows<CeProcessCanceledException> {
runBlockingCancellable { runBlockingCancellable {
throw t throw t
@@ -224,7 +224,8 @@ class RunBlockingCancellableTest : CancellationTest() {
private fun testRunBlockingCancellableChildFailure() { private fun testRunBlockingCancellableChildFailure() {
testRunBlockingCancellableChildFailure(object : Throwable() {}) testRunBlockingCancellableChildFailure(object : Throwable() {})
testRunBlockingCancellableChildFailure(ProcessCanceledException()) testRunBlockingCancellableChildDoesNotFailParent(CancellationException())
testRunBlockingCancellableChildDoesNotFailParent(ProcessCanceledException())
} }
private inline fun <reified T : Throwable> testRunBlockingCancellableChildFailure(t: T) { private inline fun <reified T : Throwable> testRunBlockingCancellableChildFailure(t: T) {
@@ -236,6 +237,14 @@ class RunBlockingCancellableTest : CancellationTest() {
assertSame(t, thrown) assertSame(t, thrown)
} }
private fun testRunBlockingCancellableChildDoesNotFailParent(t: Throwable) {
assertDoesNotThrow {
runBlockingCancellable {
Job(parent = coroutineContext.job).completeExceptionally(t)
}
}
}
@Test @Test
fun `two neighbor calls the same thread restore context properly`(): Unit = timeoutRunBlocking { fun `two neighbor calls the same thread restore context properly`(): Unit = timeoutRunBlocking {
launch { launch {

View File

@@ -81,7 +81,7 @@ class RunWithModalProgressBlockingTest : ModalCoroutineTest() {
fun rethrow(): Unit = timeoutRunBlocking { fun rethrow(): Unit = timeoutRunBlocking {
withContext(Dispatchers.EDT) { withContext(Dispatchers.EDT) {
testRunWithModalProgressBlockingRethrow(object : Throwable() {}) testRunWithModalProgressBlockingRethrow(object : Throwable() {})
testRunWithModalProgressBlockingRethrow(CancellationException()) // manual CE testRunWithModalProgressBlockingRethrowPce(CancellationException()) // manual CE
testRunWithModalProgressBlockingRethrow(ProcessCanceledException()) // manual PCE testRunWithModalProgressBlockingRethrow(ProcessCanceledException()) // manual PCE
} }
} }
@@ -95,7 +95,7 @@ class RunWithModalProgressBlockingTest : ModalCoroutineTest() {
assertSame(t, thrown) assertSame(t, thrown)
} }
private fun testRunWithModalProgressBlockingRethrow(t: CancellationException) { private fun testRunWithModalProgressBlockingRethrowPce(t: CancellationException) {
val thrown = assertThrows<CeProcessCanceledException> { val thrown = assertThrows<CeProcessCanceledException> {
runWithModalProgressBlocking { runWithModalProgressBlocking {
throw t throw t

View File

@@ -119,7 +119,7 @@ class WithModalProgressTest : ModalCoroutineTest() {
@Test @Test
fun rethrow(): Unit = timeoutRunBlocking { fun rethrow(): Unit = timeoutRunBlocking {
testWithModalProgressRethrow(object : Throwable() {}) testWithModalProgressRethrow(object : Throwable() {})
testWithModalProgressRethrow(CancellationException()) // manual CE testWithModalProgressRethrowPce(CancellationException()) // manual CE
testWithModalProgressRethrow(ProcessCanceledException()) // manual PCE testWithModalProgressRethrow(ProcessCanceledException()) // manual PCE
} }
@@ -132,8 +132,8 @@ class WithModalProgressTest : ModalCoroutineTest() {
assertSame(t, thrown) assertSame(t, thrown)
} }
private suspend fun testWithModalProgressRethrow(t: CancellationException) { private suspend inline fun <reified T : Throwable> testWithModalProgressRethrowPce(t: T) {
val thrown = assertThrows<CancellationException> { val thrown = assertThrows<T> {
withModalProgress { withModalProgress {
throw t throw t
} }

View File

@@ -1614,6 +1614,9 @@ private inline fun <X> rethrowCEasPCE(action: () -> X): X {
try { try {
return action() return action()
} }
catch (pce : ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) { catch (ce: CancellationException) {
throwAlreadyDisposedIfNotUnderIndicatorOrJob(cause = ce) throwAlreadyDisposedIfNotUnderIndicatorOrJob(cause = ce)
throw CeProcessCanceledException(ce) throw CeProcessCanceledException(ce)
@@ -1639,6 +1642,9 @@ private fun <X> runBlockingInitialization(action: suspend CoroutineScope.() -> X
@Suppress("RAW_RUN_BLOCKING") @Suppress("RAW_RUN_BLOCKING")
runBlocking(contextForInitializer, action) runBlocking(contextForInitializer, action)
} }
catch (pce : ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) { catch (ce: CancellationException) {
throw CeProcessCanceledException(ce) throw CeProcessCanceledException(ce)
} }

View File

@@ -12,7 +12,7 @@ f:com.intellij.filename.UniqueNameBuilder
- size():I - size():I
com.intellij.openapi.diagnostic.ControlFlowException com.intellij.openapi.diagnostic.ControlFlowException
c:com.intellij.openapi.progress.ProcessCanceledException c:com.intellij.openapi.progress.ProcessCanceledException
- java.lang.RuntimeException - java.util.concurrent.CancellationException
- com.intellij.openapi.diagnostic.ControlFlowException - com.intellij.openapi.diagnostic.ControlFlowException
- <init>():V - <init>():V
- p:<init>(java.lang.String):V - p:<init>(java.lang.String):V

View File

@@ -1,10 +1,12 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.progress; package com.intellij.openapi.progress;
import com.intellij.openapi.diagnostic.ControlFlowException; import com.intellij.openapi.diagnostic.ControlFlowException;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CancellationException;
/** /**
* An exception indicating that the currently running operation was terminated and should finish as soon as possible. * An exception indicating that the currently running operation was terminated and should finish as soon as possible.
* <p> * <p>
@@ -20,14 +22,15 @@ import org.jetbrains.annotations.Nullable;
* @see com.intellij.openapi.progress.ProgressIndicator#checkCanceled() * @see com.intellij.openapi.progress.ProgressIndicator#checkCanceled()
* @see <a href="https://plugins.jetbrains.com/docs/intellij/general-threading-rules.html">General Threading Rules</a> * @see <a href="https://plugins.jetbrains.com/docs/intellij/general-threading-rules.html">General Threading Rules</a>
*/ */
public class ProcessCanceledException extends RuntimeException implements ControlFlowException { public class ProcessCanceledException extends CancellationException implements ControlFlowException {
public ProcessCanceledException() { } public ProcessCanceledException() { }
public ProcessCanceledException(@Nullable Throwable cause) { public ProcessCanceledException(@Nullable Throwable cause) {
super(cause); super(cause == null ? null : cause.toString()); // repeat Throwable(Throwable) constructor logic
if (cause instanceof ProcessCanceledException) { if (cause instanceof ProcessCanceledException) {
throw new IllegalArgumentException("Must not self-wrap ProcessCanceledException: ", cause); throw new IllegalArgumentException("Must not self-wrap ProcessCanceledException: ", cause);
} }
initCause(cause);
} }
protected ProcessCanceledException(@NotNull String message) { protected ProcessCanceledException(@NotNull String message) {

View File

@@ -52,13 +52,12 @@ open class AsyncPromise<T> private constructor(internal val f: CompletableFuture
// because of the contract: get() should return null for canceled promise // because of the contract: get() should return null for canceled promise
private inline fun nullizeCancelled(value: () -> T?): T? { private inline fun nullizeCancelled(value: () -> T?): T? {
if (isCancelled) {
return null
}
return try { return try {
value() value()
} }
catch (pce: ProcessCanceledException) {
throw pce
}
catch (e: CancellationException) { catch (e: CancellationException) {
null null
} }

View File

@@ -48,9 +48,6 @@ public abstract class TwoStepCompletionProvider<T> extends ValuesCompletionProvi
break; break;
} }
} }
catch (InterruptedException | CancellationException e) {
break;
}
catch (TimeoutException ignored) { catch (TimeoutException ignored) {
} }
catch (ExecutionException e) { catch (ExecutionException e) {
@@ -61,6 +58,9 @@ public abstract class TwoStepCompletionProvider<T> extends ValuesCompletionProvi
future.cancel(true); future.cancel(true);
throw e; throw e;
} }
catch (InterruptedException | CancellationException e) {
break;
}
} }
result.stopHere(); result.stopHere();
} }

View File

@@ -555,7 +555,7 @@ public class JavaCoverageEngine extends CoverageEngine {
return createBriefReport(lineData, conditions, switches); return createBriefReport(lineData, conditions, switches);
} }
catch (ProcessCanceledException | CancellationException e) { catch (CancellationException e) {
throw e; throw e;
} }
catch (Exception e) { catch (Exception e) {

View File

@@ -2,7 +2,6 @@
package com.intellij.spellchecker; package com.intellij.spellchecker;
import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.spellchecker.dictionary.Loader; import com.intellij.spellchecker.dictionary.Loader;
@@ -47,7 +46,7 @@ public final class FileLoader implements Loader {
br.lines().forEach(consumer); br.lines().forEach(consumer);
} }
} }
catch (ProcessCanceledException | CancellationException exception) { catch (CancellationException exception) {
throw exception; throw exception;
} }
catch (Exception e) { catch (Exception e) {