[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")
runBlocking(ctx + readActionContext(), action)
}
catch (pce: ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) {
throw CeProcessCanceledException(ce)
}
@@ -169,6 +172,9 @@ fun <T> indicatorRunBlockingCancellable(indicator: ProgressIndicator, action: su
@Suppress("RAW_RUN_BLOCKING")
runBlocking(context + readActionContext(), action)
}
catch (pce: ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) {
throw CeProcessCanceledException(ce)
}
@@ -375,11 +381,15 @@ suspend fun <T> coroutineToIndicator(action: () -> T): T {
*/
@Internal
@RequiresBlockingContext
@Throws(ProcessCanceledException::class)
fun <T> blockingContextToIndicator(action: () -> T): T {
val ctx = currentThreadContext()
return try {
contextToIndicator(ctx, action)
}
catch (pce : ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) {
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;
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.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectUtil;
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;
}
catch (Throwable e) {

View File

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

View File

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

View File

@@ -323,7 +323,7 @@ public final class TreeState implements JDOMExternalizable {
try {
myPresentationData = readExternalPresentation(element);
}
catch (ProcessCanceledException | CancellationException ignored) {
catch (CancellationException ignored) {
}
catch (Exception 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 {
return deferred.getCompleted()
}
catch (pce : ProcessCanceledException) {
throw pce
}
catch (ex: CancellationException) {
throw CeProcessCanceledException(ex)
}

View File

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

View File

@@ -522,7 +522,7 @@ public final class NonBlockingReadActionImpl<T> implements NonBlockingReadAction
}
}
} catch (ProcessCanceledException e) {
cancelJob(new PceCancellationException(e));
cancelJob(e);
throw e;
}
finally {
@@ -667,17 +667,6 @@ public final class NonBlockingReadActionImpl<T> implements NonBlockingReadAction
private void failJob(@NotNull Throwable reason) {
Continuation<Unit> continuation = myChildContext.getContinuation();
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));
}
}

View File

@@ -6,8 +6,6 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.ReadConstraint
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 kotlinx.coroutines.*
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());
}
}
catch (ProcessCanceledException | CancellationException e) {
catch (CancellationException e) {
throw 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.isModalAwareContext
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.CeProcessCanceledException
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.TaskInfo
import com.intellij.openapi.progress.prepareThreadContext
import com.intellij.openapi.progress.*
import com.intellij.openapi.progress.util.*
import com.intellij.openapi.progress.util.ProgressIndicatorWithDelayedPresentation.DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS
import com.intellij.openapi.project.Project
@@ -118,6 +115,9 @@ class PlatformTaskSupport(private val cs: CoroutineScope) : TaskSupport {
try {
scope.runWithModalProgressBlockingInternal(dispatcher = null, descriptor, action)
}
catch (pce: ProcessCanceledException) {
throw pce
}
catch (ce: CancellationException) {
throw CeProcessCanceledException(ce)
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -12,7 +12,7 @@ f:com.intellij.filename.UniqueNameBuilder
- size():I
com.intellij.openapi.diagnostic.ControlFlowException
c:com.intellij.openapi.progress.ProcessCanceledException
- java.lang.RuntimeException
- java.util.concurrent.CancellationException
- com.intellij.openapi.diagnostic.ControlFlowException
- <init>():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;
import com.intellij.openapi.diagnostic.ControlFlowException;
import org.jetbrains.annotations.NotNull;
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.
* <p>
@@ -20,14 +22,15 @@ import org.jetbrains.annotations.Nullable;
* @see com.intellij.openapi.progress.ProgressIndicator#checkCanceled()
* @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(@Nullable Throwable cause) {
super(cause);
super(cause == null ? null : cause.toString()); // repeat Throwable(Throwable) constructor logic
if (cause instanceof ProcessCanceledException) {
throw new IllegalArgumentException("Must not self-wrap ProcessCanceledException: ", cause);
}
initCause(cause);
}
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
private inline fun nullizeCancelled(value: () -> T?): T? {
if (isCancelled) {
return null
}
return try {
value()
}
catch (pce: ProcessCanceledException) {
throw pce
}
catch (e: CancellationException) {
null
}

View File

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

View File

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

View File

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