diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java index 752fe2b2efc4..41960e824f1d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java @@ -16,6 +16,7 @@ import com.intellij.openapi.util.NlsContexts; import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy; import com.intellij.ui.IdeUICustomization; import com.intellij.util.Alarm; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -154,7 +155,7 @@ public class SingleConfigurableEditor extends DialogWrapper { } } catch (ConfigurationException e) { - if (e.getMessage() != null) { + if (!processException(e) && e.getMessage() != null) { if (myProject != null) { Messages.showMessageDialog(myProject, e.getMessage(), e.getTitle(), Messages.getErrorIcon()); } @@ -168,6 +169,11 @@ public class SingleConfigurableEditor extends DialogWrapper { super.doOKAction(); } + @ApiStatus.Internal + protected boolean processException(ConfigurationException configurationException) { + return false; + } + protected static String createDimensionKey(Configurable configurable) { String displayName = configurable.getDisplayName(); displayName = displayName.replaceAll("\n", "_").replaceAll(" ", "_"); diff --git a/platform/settings-sync-core/src/com/intellij/settingsSync/core/AbstractServerCommunicator.kt b/platform/settings-sync-core/src/com/intellij/settingsSync/core/AbstractServerCommunicator.kt index a93aa70ac26b..51507be57f5a 100644 --- a/platform/settings-sync-core/src/com/intellij/settingsSync/core/AbstractServerCommunicator.kt +++ b/platform/settings-sync-core/src/com/intellij/settingsSync/core/AbstractServerCommunicator.kt @@ -71,7 +71,7 @@ abstract class AbstractServerCommunicator : SettingsSyncRemoteCommunicator, Disp * @throws IOException If an I/O error occurs while attempting to retrieve the version information. */ @Throws(IOException::class) - protected abstract fun getLatestVersion(filePath: String) : String? + abstract fun getLatestVersion(filePath: String) : String? @Throws(IOException::class) protected abstract fun deleteFileInternal(filePath: String) @@ -79,7 +79,7 @@ abstract class AbstractServerCommunicator : SettingsSyncRemoteCommunicator, Disp @VisibleForTesting @Throws(IOException::class, SecurityException::class) - protected fun currentSnapshotFilePath(): Pair? { + protected open fun currentSnapshotFilePath(): Pair? { try { val crossIdeSyncEnabled = isFileExists(CROSS_IDE_SYNC_MARKER_FILE) if (!myTemporary && crossIdeSyncEnabled != SettingsSyncLocalSettings.getInstance().isCrossIdeSyncEnabled) { @@ -106,7 +106,7 @@ abstract class AbstractServerCommunicator : SettingsSyncRemoteCommunicator, Disp @VisibleForTesting - internal fun sendSnapshotFile( + fun sendSnapshotFile( inputStream: InputStream, knownServerVersion: String?, force: Boolean, @@ -143,6 +143,10 @@ abstract class AbstractServerCommunicator : SettingsSyncRemoteCommunicator, Disp // errors are thrown as exceptions and are handled above return SettingsSyncPushResult.Success(pushedVersion) } + catch (ive: InvalidVersionIdException) { + LOG.info("Rejected: version doesn't match the version on server: ${ive.message}") + return SettingsSyncPushResult.Rejected + } catch (e: Throwable) { return SettingsSyncPushResult.Error(e.message ?: defaultMessage) } @@ -156,7 +160,7 @@ abstract class AbstractServerCommunicator : SettingsSyncRemoteCommunicator, Disp requestSuccessful() when (latestVersion) { null -> return ServerState.FileNotExists - SettingsSyncLocalSettings.getInstance().knownAndAppliedServerId -> return ServerState.UpToDate + getKnownAndAppliedServerId() -> return ServerState.UpToDate else -> return ServerState.UpdateNeeded } } @@ -166,6 +170,8 @@ abstract class AbstractServerCommunicator : SettingsSyncRemoteCommunicator, Disp } } + open fun getKnownAndAppliedServerId(): String? = SettingsSyncLocalSettings.getInstance().knownAndAppliedServerId + override fun receiveUpdates(): UpdateResult { LOG.info("Receiving settings snapshot from the cloud config server...") try { @@ -214,10 +220,6 @@ abstract class AbstractServerCommunicator : SettingsSyncRemoteCommunicator, Disp requestSuccessful() return pushResult } - catch (ive: InvalidVersionIdException) { - LOG.info("Rejected: version doesn't match the version on server: ${ive.message}") - return SettingsSyncPushResult.Rejected - } catch (e: Throwable) { val message = handleRemoteError(e) return SettingsSyncPushResult.Error(message) diff --git a/platform/settings-sync-core/src/com/intellij/settingsSync/core/SettingsSnapshotZipSerializer.kt b/platform/settings-sync-core/src/com/intellij/settingsSync/core/SettingsSnapshotZipSerializer.kt index a29f94e3c60d..a80a5e66a89c 100644 --- a/platform/settings-sync-core/src/com/intellij/settingsSync/core/SettingsSnapshotZipSerializer.kt +++ b/platform/settings-sync-core/src/com/intellij/settingsSync/core/SettingsSnapshotZipSerializer.kt @@ -23,7 +23,7 @@ import kotlin.io.path.isRegularFile import kotlin.io.path.name import kotlin.io.path.readText -internal object SettingsSnapshotZipSerializer { +object SettingsSnapshotZipSerializer { private const val METAINFO = ".metainfo" private const val INFO = "info.json" const val PLUGINS = "plugins.json" @@ -147,7 +147,7 @@ internal object SettingsSnapshotZipSerializer { return SettingsSyncPluginsState(emptyMap()) } - private fun serializeMetaInfo(snapshotMetaInfo: SettingsSnapshot.MetaInfo): ByteArray { + fun serializeMetaInfo(snapshotMetaInfo: SettingsSnapshot.MetaInfo): ByteArray { val formattedDate = DateTimeFormatter.ISO_INSTANT.format(snapshotMetaInfo.dateCreated) val metaInfo = MetaInfo().apply { date = formattedDate @@ -186,7 +186,7 @@ internal object SettingsSnapshotZipSerializer { return SettingsSnapshot.MetaInfo(Instant.now(), appInfo = null) } - private class MetaInfo { + class MetaInfo { lateinit var date: String lateinit var applicationId: String var buildNumber: String = "" diff --git a/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/CloudConfigServerCommunicator.kt b/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/CloudConfigServerCommunicator.kt index 5184329d2c7b..10d3b2a6e856 100644 --- a/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/CloudConfigServerCommunicator.kt +++ b/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/CloudConfigServerCommunicator.kt @@ -5,6 +5,7 @@ import com.intellij.ide.plugins.PluginManagerCore.isRunningFromSources import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.util.JDOMUtil import com.intellij.settingsSync.core.AbstractServerCommunicator +import com.intellij.settingsSync.core.InvalidVersionIdException import com.intellij.settingsSync.core.SettingsSyncBundle import com.intellij.settingsSync.core.SettingsSyncEventListener import com.intellij.settingsSync.core.SettingsSyncEvents @@ -26,7 +27,7 @@ import java.net.URI import java.net.http.HttpResponse import java.util.concurrent.atomic.AtomicReference -internal open class CloudConfigServerCommunicator(private val serverUrl: String?, private val jbaAuthService: JBAAuthService) +open class CloudConfigServerCommunicator(private val serverUrl: String?, private val jbaAuthService: JBAAuthService) : AbstractServerCommunicator() { private val clientVersionContext = CloudConfigVersionContext() @@ -128,7 +129,13 @@ internal open class CloudConfigServerCommunicator(private val serverUrl: String? override fun writeFileInternal(filePath: String, versionId: String?, content: InputStream) : String? { return clientVersionContext.doWithVersion(filePath, versionId) { filePath -> - client.write(filePath, content) + try { + client.write(filePath, content) + } + catch (e: com.jetbrains.cloudconfig.exception.InvalidVersionIdException) { + throw InvalidVersionIdException(e.message ?: "Invalid version id exception from server", e) + } + val actualVersion: String? = clientVersionContext.get(filePath) if (actualVersion == null) { diff --git a/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/JbaCommunicatorProvider.kt b/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/JbaCommunicatorProvider.kt index 7fa4c771886d..db87d4ff3710 100644 --- a/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/JbaCommunicatorProvider.kt +++ b/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/JbaCommunicatorProvider.kt @@ -12,7 +12,7 @@ class JbaCommunicatorProvider(cs: CoroutineScope) : SettingsSyncCommunicatorProv private val authServiceLazy = lazy { JBAAuthService(cs) } override val providerCode: String - get() = "jba" + get() = JBA_PROVIDER_CODE override val authService: SettingsSyncAuthService get() { @@ -27,4 +27,8 @@ class JbaCommunicatorProvider(cs: CoroutineScope) : SettingsSyncCommunicatorProv }.value override fun dispose() {} + + companion object { + const val JBA_PROVIDER_CODE: String = "jba" + } } \ No newline at end of file diff --git a/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/auth/JBAAuthService.kt b/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/auth/JBAAuthService.kt index 5d67a82ea16d..940ae948d835 100644 --- a/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/auth/JBAAuthService.kt +++ b/plugins/settings-sync/jba/src/com/intellij/settingsSync/jba/auth/JBAAuthService.kt @@ -79,7 +79,7 @@ private val LOG = logger() private const val JBA_USER_ID = "jba" private const val JBA_PROVIDER_CODE = "jba" -internal class JBAAuthService(private val cs: CoroutineScope) : SettingsSyncAuthService { +class JBAAuthService(private val cs: CoroutineScope) : SettingsSyncAuthService { @Volatile private var invalidatedIdToken: String? = null