From 4598e147dae62f69dd50342c8aaff50376cf9653 Mon Sep 17 00:00:00 2001 From: Nicolas QUINQUENEL Date: Mon, 30 Sep 2024 16:19:37 +0200 Subject: [PATCH] Improve task behavior when failing --- .../intellij/config/global/wizard/AuthStep.java | 5 ++--- .../project/SonarLintProjectBindPanel.java | 4 ++-- .../ConfigureNotificationsAction.kt | 4 ++-- .../tasks/CheckNotificationsSupportedTask.java | 11 ++++++----- .../intellij/tasks/ConnectionTestTask.kt | 6 ++---- .../intellij/tasks/GetOrganizationTask.java | 14 +++++++------- .../intellij/tasks/GetOrganizationsTask.java | 17 +++++++++-------- .../tasks/ServerDownloadProjectTask.java | 10 +++++++--- .../org/sonarlint/intellij/util/ThreadUtils.kt | 6 ++++++ 9 files changed, 43 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/sonarlint/intellij/config/global/wizard/AuthStep.java b/src/main/java/org/sonarlint/intellij/config/global/wizard/AuthStep.java index 2a1b88c1a5..7700cf07e5 100644 --- a/src/main/java/org/sonarlint/intellij/config/global/wizard/AuthStep.java +++ b/src/main/java/org/sonarlint/intellij/config/global/wizard/AuthStep.java @@ -48,7 +48,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.sonarlint.intellij.common.util.SonarLintUtils; -import org.sonarlint.intellij.config.global.ServerConnection; import org.sonarlint.intellij.core.BackendService; import org.sonarlint.intellij.tasks.ConnectionTestTask; import org.sonarlint.intellij.util.GlobalLogOutput; @@ -230,8 +229,8 @@ private void tryQueryIfNotificationsSupported() throws CommitStepException { } private void checkConnection() throws CommitStepException { - ServerConnection tmpServer = model.createConnectionWithoutOrganization(); - ConnectionTestTask test = new ConnectionTestTask(tmpServer); + var tmpServer = model.createConnectionWithoutOrganization(); + var test = new ConnectionTestTask(tmpServer); var msg = "Failed to connect to the server. Please check the configuration."; ValidateConnectionResponse result; diff --git a/src/main/java/org/sonarlint/intellij/config/project/SonarLintProjectBindPanel.java b/src/main/java/org/sonarlint/intellij/config/project/SonarLintProjectBindPanel.java index e39b2cf14f..0bba0cd5b6 100644 --- a/src/main/java/org/sonarlint/intellij/config/project/SonarLintProjectBindPanel.java +++ b/src/main/java/org/sonarlint/intellij/config/project/SonarLintProjectBindPanel.java @@ -62,8 +62,8 @@ import org.sonarlint.intellij.common.ui.SonarLintConsole; import org.sonarlint.intellij.config.global.ServerConnection; import org.sonarlint.intellij.config.global.SonarLintGlobalConfigurable; -import org.sonarlint.intellij.tasks.ServerDownloadProjectTask; import org.sonarlint.intellij.sharing.ConfigurationSharing; +import org.sonarlint.intellij.tasks.ServerDownloadProjectTask; import org.sonarsource.sonarlint.core.rpc.protocol.backend.connection.projects.SonarProjectDto; import static java.awt.GridBagConstraints.EAST; @@ -162,7 +162,7 @@ private Map downloadProjectList(ServerConnection select try { return ProgressManager.getInstance().run(downloadTask); } catch (Exception e) { - var msg = "Failed to download list of projects. Please check the logs for more details."; + var msg = "Failed to download list of projects. Reason: " + e.getMessage(); getService(project, SonarLintConsole.class).error(e.getMessage()); Messages.showErrorDialog(rootPanel, msg, "Error Downloading Project List"); return null; diff --git a/src/main/java/org/sonarlint/intellij/notifications/ConfigureNotificationsAction.kt b/src/main/java/org/sonarlint/intellij/notifications/ConfigureNotificationsAction.kt index 4f15c59c69..f7b056953c 100644 --- a/src/main/java/org/sonarlint/intellij/notifications/ConfigureNotificationsAction.kt +++ b/src/main/java/org/sonarlint/intellij/notifications/ConfigureNotificationsAction.kt @@ -43,8 +43,8 @@ class ConfigureNotificationsAction(private val connectionName: String, private v serverConnections[serverConnections.indexOf(connectionToEdit)] = editedConnection Settings.getGlobalSettings().serverConnections = serverConnections } - } else if (e.project != null) { - SonarLintConsole.get(e.project!!).error("Unable to find connection with name: $connectionName") + } else { + SonarLintConsole.get(project).error("Unable to find connection with name: $connectionName") notification.expire() } } diff --git a/src/main/java/org/sonarlint/intellij/tasks/CheckNotificationsSupportedTask.java b/src/main/java/org/sonarlint/intellij/tasks/CheckNotificationsSupportedTask.java index 14cbcfd55e..6948c2a186 100644 --- a/src/main/java/org/sonarlint/intellij/tasks/CheckNotificationsSupportedTask.java +++ b/src/main/java/org/sonarlint/intellij/tasks/CheckNotificationsSupportedTask.java @@ -19,7 +19,6 @@ */ package org.sonarlint.intellij.tasks; -import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import org.jetbrains.annotations.NotNull; @@ -29,6 +28,7 @@ import org.sonarlint.intellij.core.BackendService; import static org.sonarlint.intellij.util.ProgressUtils.waitForFuture; +import static org.sonarlint.intellij.util.ThreadUtilsKt.computeOnPooledThreadWithoutCatching; /** * Only useful for SonarQube, since we know notifications are available in SonarCloud @@ -39,17 +39,18 @@ public class CheckNotificationsSupportedTask extends Task.Modal { private boolean notificationsSupported = false; public CheckNotificationsSupportedTask(ServerConnection connection) { - super(null, "Check if smart notifications are supported", true); + super(null, "Check If Smart Notifications Are Supported", true); this.connection = connection; } @Override public void run(@NotNull ProgressIndicator indicator) { - indicator.setIndeterminate(false); + indicator.setIndeterminate(true); try { indicator.setText("Checking support of notifications"); - notificationsSupported = waitForFuture(indicator, SonarLintUtils.getService(BackendService.class).checkSmartNotificationsSupported(connection)).isSuccess(); - } catch (ProcessCanceledException e) { + notificationsSupported = Boolean.TRUE.equals(computeOnPooledThreadWithoutCatching("Check Smart Notifications Supported Task", + () -> waitForFuture(indicator, SonarLintUtils.getService(BackendService.class).checkSmartNotificationsSupported(connection)).isSuccess())); + } catch (Exception e) { if (myProject != null) { SonarLintConsole.get(myProject).error("Failed to check notifications", e); } diff --git a/src/main/java/org/sonarlint/intellij/tasks/ConnectionTestTask.kt b/src/main/java/org/sonarlint/intellij/tasks/ConnectionTestTask.kt index 02e71f69b9..cee82f4bfa 100644 --- a/src/main/java/org/sonarlint/intellij/tasks/ConnectionTestTask.kt +++ b/src/main/java/org/sonarlint/intellij/tasks/ConnectionTestTask.kt @@ -19,13 +19,13 @@ */ package org.sonarlint.intellij.tasks -import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.Task import org.sonarlint.intellij.common.util.SonarLintUtils import org.sonarlint.intellij.config.global.ServerConnection import org.sonarlint.intellij.core.BackendService import org.sonarlint.intellij.util.ProgressUtils.waitForFuture +import org.sonarlint.intellij.util.computeOnPooledThreadWithoutCatching import org.sonarsource.sonarlint.core.rpc.protocol.backend.connection.validate.ValidateConnectionResponse class ConnectionTestTask(private val server: ServerConnection) : @@ -36,10 +36,8 @@ class ConnectionTestTask(private val server: ServerConnection) : override fun compute(indicator: ProgressIndicator): ValidateConnectionResponse? { indicator.text = "Connecting to " + server.hostUrl + "\u2026" indicator.isIndeterminate = true - return try { + return computeOnPooledThreadWithoutCatching("Validate Connection Task") { waitForFuture(indicator, SonarLintUtils.getService(BackendService::class.java).validateConnection(server)) - } catch (e: ProcessCanceledException) { - null } } } diff --git a/src/main/java/org/sonarlint/intellij/tasks/GetOrganizationTask.java b/src/main/java/org/sonarlint/intellij/tasks/GetOrganizationTask.java index 059daab3f1..49a99b9b21 100644 --- a/src/main/java/org/sonarlint/intellij/tasks/GetOrganizationTask.java +++ b/src/main/java/org/sonarlint/intellij/tasks/GetOrganizationTask.java @@ -29,7 +29,7 @@ import org.sonarsource.sonarlint.core.rpc.protocol.backend.connection.org.OrganizationDto; import static org.sonarlint.intellij.util.ProgressUtils.waitForFuture; -import static org.sonarlint.intellij.util.ThreadUtilsKt.computeOnPooledThread; +import static org.sonarlint.intellij.util.ThreadUtilsKt.computeOnPooledThreadWithoutCatching; public class GetOrganizationTask extends Task.Modal { private final ServerConnection server; @@ -46,15 +46,15 @@ public GetOrganizationTask(ServerConnection server, String organizationKey) { @Override public void run(@NotNull ProgressIndicator indicator) { - indicator.setText("Connecting to SonarCloud\u2026"); - indicator.setIndeterminate(false); - + indicator.setIndeterminate(true); try { indicator.setText("Searching organization"); - organization = computeOnPooledThread("Get User Organizations", () -> - waitForFuture(indicator, SonarLintUtils.getService(BackendService.class).getOrganization(server, organizationKey)).getOrganization()); + organization = computeOnPooledThreadWithoutCatching("Get User Organization Task", + () -> waitForFuture(indicator, SonarLintUtils.getService(BackendService.class).getOrganization(server, organizationKey)).getOrganization()); } catch (Exception e) { - SonarLintConsole.get(myProject).error("Failed to fetch organizations", e); + if (myProject != null) { + SonarLintConsole.get(myProject).error("Failed to fetch organization", e); + } exception = e; } } diff --git a/src/main/java/org/sonarlint/intellij/tasks/GetOrganizationsTask.java b/src/main/java/org/sonarlint/intellij/tasks/GetOrganizationsTask.java index 2ef2f9304a..cccffb0646 100644 --- a/src/main/java/org/sonarlint/intellij/tasks/GetOrganizationsTask.java +++ b/src/main/java/org/sonarlint/intellij/tasks/GetOrganizationsTask.java @@ -30,7 +30,7 @@ import org.sonarsource.sonarlint.core.rpc.protocol.backend.connection.org.OrganizationDto; import static org.sonarlint.intellij.util.ProgressUtils.waitForFuture; -import static org.sonarlint.intellij.util.ThreadUtilsKt.computeOnPooledThread; +import static org.sonarlint.intellij.util.ThreadUtilsKt.computeOnPooledThreadWithoutCatching; /** * Only useful for SonarCloud @@ -41,20 +41,21 @@ public class GetOrganizationsTask extends Task.Modal { private List organizations; public GetOrganizationsTask(ServerConnection connection) { - super(null, "Fetch organizations from SonarCloud", true); + super(null, "Fetch Organizations from SonarCloud", true); this.connection = connection; } @Override public void run(@NotNull ProgressIndicator indicator) { - indicator.setText("Connecting to " + connection.getHostUrl() + "\u2026"); - indicator.setIndeterminate(false); - + indicator.setText("Searching organizations"); + indicator.setIndeterminate(true); try { - organizations = computeOnPooledThread("Get User Organizations",() -> - waitForFuture(indicator, SonarLintUtils.getService(BackendService.class).listUserOrganizations(connection)).getUserOrganizations()); + organizations = computeOnPooledThreadWithoutCatching("Get User Organizations Task", + () -> waitForFuture(indicator, SonarLintUtils.getService(BackendService.class).listUserOrganizations(connection)).getUserOrganizations()); } catch (Exception e) { - SonarLintConsole.get(myProject).error("Failed to fetch organizations", e); + if (myProject != null) { + SonarLintConsole.get(myProject).error("Failed to fetch organizations", e); + } exception = e; } } diff --git a/src/main/java/org/sonarlint/intellij/tasks/ServerDownloadProjectTask.java b/src/main/java/org/sonarlint/intellij/tasks/ServerDownloadProjectTask.java index 4b3ace19fc..99406cbcc4 100644 --- a/src/main/java/org/sonarlint/intellij/tasks/ServerDownloadProjectTask.java +++ b/src/main/java/org/sonarlint/intellij/tasks/ServerDownloadProjectTask.java @@ -36,23 +36,27 @@ public class ServerDownloadProjectTask extends Task.WithResult, Exception> { private final ServerConnection server; + private final Project project; public ServerDownloadProjectTask(Project project, ServerConnection server) { super(project, "Downloading Project List", true); + this.project = project; this.server = server; } @Override protected Map compute(@NotNull ProgressIndicator indicator) { try { - return computeOnPooledThreadWithoutCatching(myProject, "Download Projects", () -> + indicator.setIndeterminate(true); + indicator.setText("Downloading projects"); + return computeOnPooledThreadWithoutCatching(project, "Download Projects Task", + () -> waitForFuture(indicator, getService(BackendService.class) .getAllProjects(server)) .getSonarProjects() .stream().collect(Collectors.toMap(SonarProjectDto::getKey, p -> p))); - } catch (Exception e) { - SonarLintConsole.get(myProject).error("Failed to download list of projects", e); + SonarLintConsole.get(project).error("Failed to download list of projects", e); throw e; } } diff --git a/src/main/java/org/sonarlint/intellij/util/ThreadUtils.kt b/src/main/java/org/sonarlint/intellij/util/ThreadUtils.kt index 9cfae33896..a2f5e6bff0 100644 --- a/src/main/java/org/sonarlint/intellij/util/ThreadUtils.kt +++ b/src/main/java/org/sonarlint/intellij/util/ThreadUtils.kt @@ -61,6 +61,12 @@ fun computeOnPooledThreadWithoutCatching(project: Project, taskName: String, }, taskName, Duration.ofSeconds(30)) } +fun computeOnPooledThreadWithoutCatching(taskName: String, callable: Callable): T? { + return waitForTaskWithoutCatching(ApplicationManager.getApplication().executeOnPooledThread { + callable.call() + }, taskName, Duration.ofSeconds(30)) +} + fun computeOnPooledThread(taskName: String, callable: Callable): T? { return waitForTask(ApplicationManager.getApplication().executeOnPooledThread { callable.call()