From 37152190a57a5f8baf1f9b14ecc76263c0b08a28 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 25 Feb 2025 12:33:30 +0100 Subject: [PATCH] IJPL-172200 IJPL-176167 prevent 'LaterInvocator.forceLeaveAllModals'-induced errors from cancelling IDE exit (cherry picked from commit ee9547bb2963ffcdc7ebb832a7f28621cdcfe82f) IJ-CR-156309 GitOrigin-RevId: 633c237c621400b1a9d48482f859b2931aee38b5 --- .../src/SaveAndSyncHandlerImpl.kt | 18 ++++++++++-------- .../application/impl/ApplicationImpl.java | 9 +++++++-- .../progress/shared/src/TaskCancellation.kt | 2 ++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/platform/configuration-store-impl/src/SaveAndSyncHandlerImpl.kt b/platform/configuration-store-impl/src/SaveAndSyncHandlerImpl.kt index 5ab311ce5d82..60448aefcad6 100644 --- a/platform/configuration-store-impl/src/SaveAndSyncHandlerImpl.kt +++ b/platform/configuration-store-impl/src/SaveAndSyncHandlerImpl.kt @@ -285,16 +285,18 @@ private class SaveAndSyncHandlerImpl(private val coroutineScope: CoroutineScope) title = getProgressTitle(componentManager), cancellation = TaskCancellation.nonCancellable(), ) { - // ensure that is fully canceled - currentJob?.join() + withContext(NonCancellable) { + // ensure that is fully canceled + currentJob?.join() - isSavedSuccessfully = saveSettings(componentManager, forceSavingAllSettings = true) + isSavedSuccessfully = saveSettings(componentManager, forceSavingAllSettings = true) - if (project != null && !ApplicationManager.getApplication().isUnitTestMode) { - val stateStore = project.stateStore - val path = if (stateStore.storageScheme == StorageScheme.DIRECTORY_BASED) stateStore.projectBasePath else stateStore.projectFilePath - // update last modified for all project files modified between project open and close - ConversionService.getInstance()?.saveConversionResult(path) + if (project != null && !ApplicationManager.getApplication().isUnitTestMode) { + val stateStore = project.stateStore + val path = if (stateStore.storageScheme == StorageScheme.DIRECTORY_BASED) stateStore.projectBasePath else stateStore.projectFilePath + // update last modified for all project files modified between project open and close + ConversionService.getInstance()?.saveConversionResult(path) + } } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 449fb3d1b166..d201c8c4e583 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -674,8 +674,13 @@ public final class ApplicationImpl extends ClientAwareComponentManager implement stopServicePreloading(); if (BitUtil.isSet(flags, SAVE)) { - TraceKt.use(tracer.spanBuilder("saveSettingsOnExit"), - __ -> SaveAndSyncHandler.getInstance().saveSettingsUnderModalProgress(this)); + try { + TraceKt.use(tracer.spanBuilder("saveSettingsOnExit"), + __ -> SaveAndSyncHandler.getInstance().saveSettingsUnderModalProgress(this)); + } + catch (Throwable e) { + logErrorDuringExit("Failed to save settings", e); + } } if (isInstantShutdownPossible()) { diff --git a/platform/progress/shared/src/TaskCancellation.kt b/platform/progress/shared/src/TaskCancellation.kt index a6e458209bd1..2eae9cfa15eb 100644 --- a/platform/progress/shared/src/TaskCancellation.kt +++ b/platform/progress/shared/src/TaskCancellation.kt @@ -23,6 +23,8 @@ sealed interface TaskCancellation { companion object { /** * @return a cancellation instance, which means that the cancel button should not be displayed in the UI + * + * It does not indicate that the task is inside [kotlinx.coroutines.NonCancellable] section. */ @Contract(pure = true) @JvmStatic