Gradle: error handling refactoring
authorVladislav.Soroka <Vladislav.Soroka@jetbrains.com>
Wed, 8 May 2019 05:58:59 +0000 (08:58 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Wed, 8 May 2019 08:03:13 +0000 (11:03 +0300)
GitOrigin-RevId: c5ad322981e63fef131e3ee60fe9ff4071060768

15 files changed:
platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/ExternalSystemException.java
plugins/gradle/java/src/service/project/JavaGradleProjectResolver.java
plugins/gradle/src/org/jetbrains/plugins/gradle/issue/BuildIssueException.java [new file with mode: 0644]
plugins/gradle/src/org/jetbrains/plugins/gradle/issue/GradleIssueData.kt [new file with mode: 0644]
plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleExecutionHelper.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/notification/GradleNotificationExtension.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectImportErrorHandler.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/AbstractProjectResolverExtension.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseProjectImportErrorHandler.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/DefaultProjectResolverContext.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverExtension.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java
plugins/gradle/testSources/org/jetbrains/plugins/gradle/service/project/BaseProjectImportErrorHandlerTest.java

index d379696cfa5716fbf0b33262ed478a38771e3c84..427144cadf899ae68096ed057c12486eff495733 100644 (file)
@@ -25,6 +25,7 @@ public class ExternalSystemException extends RuntimeException {
 
   @NotNull
   private final String[] myQuickFixes;
+  private boolean myCauseInitialized;
 
   public ExternalSystemException() {
     this(null, (Throwable)null);
@@ -88,6 +89,16 @@ public ExternalSystemException(@Nullable String message, @Nullable Throwable cau
     s.println(myOriginalReason);
   }
 
+  public synchronized boolean isCauseInitialized() {
+    return myCauseInitialized;
+  }
+
+  @Override
+  public synchronized Throwable initCause(Throwable cause) {
+    myCauseInitialized = true;
+    return super.initCause(cause);
+  }
+
   @Nullable
   private static String extractMessage(@Nullable String message, @Nullable Throwable cause) {
     StringBuilder buffer = new StringBuilder();
index 163b66eb70fe7302d36a4867be1d180973f6aaed..57385cf67e88b5310f0c02cfe2e50cb5560cf7ce 100644 (file)
@@ -15,6 +15,7 @@ import com.intellij.pom.java.LanguageLevel;
 import com.intellij.util.Consumer;
 import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
+import org.gradle.tooling.model.build.BuildEnvironment;
 import org.gradle.tooling.model.idea.IdeaModule;
 import org.gradle.tooling.model.idea.IdeaProject;
 import org.jetbrains.annotations.NotNull;
@@ -91,23 +92,26 @@ public class JavaGradleProjectResolver extends AbstractProjectResolverExtension
 
   @NotNull
   @Override
-  public ExternalSystemException getUserFriendlyError(@NotNull Throwable error,
+  public ExternalSystemException getUserFriendlyError(@Nullable BuildEnvironment buildEnvironment,
+                                                      @NotNull Throwable error,
                                                       @NotNull String projectPath,
                                                       @Nullable String buildFilePath) {
-    ExternalSystemException friendlyError = new JavaProjectImportErrorHandler().getUserFriendlyError(error, projectPath, buildFilePath);
+    ExternalSystemException friendlyError =
+      new JavaProjectImportErrorHandler().getUserFriendlyError(buildEnvironment, error, projectPath, buildFilePath);
     if (friendlyError != null) {
       if (friendlyError.getCause() == null) {
         friendlyError.initCause(error);
       }
       return friendlyError;
     }
-    return super.getUserFriendlyError(error, projectPath, buildFilePath);
+    return super.getUserFriendlyError(buildEnvironment, error, projectPath, buildFilePath);
   }
 
   private static class JavaProjectImportErrorHandler extends AbstractProjectImportErrorHandler {
     @Nullable
     @Override
-    public ExternalSystemException getUserFriendlyError(@NotNull Throwable error,
+    public ExternalSystemException getUserFriendlyError(@Nullable BuildEnvironment buildEnvironment,
+                                                        @NotNull Throwable error,
                                                         @NotNull String projectPath,
                                                         @Nullable String buildFilePath) {
       GradleExecutionErrorHandler executionErrorHandler = new GradleExecutionErrorHandler(error, projectPath, buildFilePath);
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/issue/BuildIssueException.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/issue/BuildIssueException.java
new file mode 100644 (file)
index 0000000..755f7a5
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2000-2019 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.
+package org.jetbrains.plugins.gradle.issue;
+
+import com.intellij.build.issue.BuildIssue;
+import com.intellij.openapi.externalSystem.model.ExternalSystemException;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Vladislav.Soroka
+ */
+@ApiStatus.Experimental
+public class BuildIssueException extends ExternalSystemException {
+  private final BuildIssue myBuildIssue;
+
+  public BuildIssueException(@NotNull BuildIssue issue) {
+    super(issue.getDescription(), getQuickfixIds(issue));
+    myBuildIssue = issue;
+  }
+
+  public BuildIssue getBuildIssue() {
+    return myBuildIssue;
+  }
+
+  private static String[] getQuickfixIds(@NotNull BuildIssue issue) {
+    return issue.getQuickFixes().stream().map(fix -> fix.getId()).toArray(String[]::new);
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/issue/GradleIssueData.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/issue/GradleIssueData.kt
new file mode 100644 (file)
index 0000000..6e8c1ff
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2000-2019 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.
+package org.jetbrains.plugins.gradle.issue
+
+import com.intellij.build.issue.BuildIssueData
+import org.gradle.tooling.model.build.BuildEnvironment
+import org.jetbrains.annotations.ApiStatus
+
+/**
+ * @author Vladislav.Soroka
+ */
+@ApiStatus.Experimental
+class GradleIssueData(val buildEnvironment: BuildEnvironment?,
+                      val projectPath: String,
+                      val buildFilePath: String?,
+                      val error: Throwable,
+                      val rootCause: Throwable,
+                      val location: String?) : BuildIssueData
index d4b6bfb6db544d88f2524793d2aba23967fbb6ec..c90b25cc34a2d7650891c9cd25293e1a98741d68 100644 (file)
@@ -578,29 +578,35 @@ public class GradleExecutionHelper {
                                                      @NotNull ExternalSystemTaskId taskId,
                                                      @NotNull ExternalSystemTaskNotificationListener listener,
                                                      @Nullable CancellationTokenSource cancellationTokenSource) {
-    ModelBuilder<BuildEnvironment> modelBuilder = connection.model(BuildEnvironment.class);
-    if (cancellationTokenSource != null) {
-      modelBuilder.withCancellationToken(cancellationTokenSource.token());
-    }
-    // do not use connection.getModel methods since it doesn't allow to handle progress events
-    // and we can miss gradle tooling client side events like distribution download.
-    GradleProgressListener gradleProgressListener = new GradleProgressListener(listener, taskId);
-    modelBuilder.addProgressListener((ProgressListener)gradleProgressListener);
-    modelBuilder.addProgressListener((org.gradle.tooling.events.ProgressListener)gradleProgressListener);
-    modelBuilder.setStandardOutput(new OutputWrapper(listener, taskId, true));
-    modelBuilder.setStandardError(new OutputWrapper(listener, taskId, false));
-
-    final BuildEnvironment buildEnvironment = modelBuilder.get();
-    if (LOG.isDebugEnabled()) {
-      try {
-        LOG.debug("Gradle version: " + buildEnvironment.getGradle().getGradleVersion());
-        LOG.debug("Gradle java home: " + buildEnvironment.getJava().getJavaHome());
-        LOG.debug("Gradle jvm arguments: " + buildEnvironment.getJava().getJvmArguments());
-      }
-      catch (Throwable t) {
-        LOG.debug(t);
+    BuildEnvironment buildEnvironment = null;
+    try {
+      ModelBuilder<BuildEnvironment> modelBuilder = connection.model(BuildEnvironment.class);
+      if (cancellationTokenSource != null) {
+        modelBuilder.withCancellationToken(cancellationTokenSource.token());
+      }
+      // do not use connection.getModel methods since it doesn't allow to handle progress events
+      // and we can miss gradle tooling client side events like distribution download.
+      GradleProgressListener gradleProgressListener = new GradleProgressListener(listener, taskId);
+      modelBuilder.addProgressListener((ProgressListener)gradleProgressListener);
+      modelBuilder.addProgressListener((org.gradle.tooling.events.ProgressListener)gradleProgressListener);
+      modelBuilder.setStandardOutput(new OutputWrapper(listener, taskId, true));
+      modelBuilder.setStandardError(new OutputWrapper(listener, taskId, false));
+
+      buildEnvironment = modelBuilder.get();
+      if (LOG.isDebugEnabled()) {
+        try {
+          LOG.debug("Gradle version: " + buildEnvironment.getGradle().getGradleVersion());
+          LOG.debug("Gradle java home: " + buildEnvironment.getJava().getJavaHome());
+          LOG.debug("Gradle jvm arguments: " + buildEnvironment.getJava().getJvmArguments());
+        }
+        catch (Throwable t) {
+          LOG.debug(t);
+        }
       }
     }
+    catch (Throwable t) {
+      LOG.debug(t);
+    }
     return buildEnvironment;
   }
 
index 60a0aeb5e2f7365dc1fc76675f83c16e5638339e..666bc57719552e04dc58eca6f748f330570cf3f4 100644 (file)
@@ -25,6 +25,9 @@ import com.intellij.openapi.externalSystem.service.notification.callback.OpenExt
 import com.intellij.openapi.project.Project;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import com.intellij.build.issue.BuildIssue;
+import org.jetbrains.plugins.gradle.issue.BuildIssueException;
+import com.intellij.build.issue.BuildIssueQuickFix;
 import org.jetbrains.plugins.gradle.util.GradleConstants;
 
 import java.io.ObjectStreamException;
@@ -47,7 +50,7 @@ public class GradleNotificationExtension implements ExternalSystemNotificationEx
       // compiler errors should be handled by BuildOutputParsers
       return true;
     }
-    if(unwrapped.getCause() instanceof ObjectStreamException) {
+    if (unwrapped.getCause() instanceof ObjectStreamException) {
       // gradle tooling internal serialization issues
       return true;
     }
@@ -76,9 +79,15 @@ public class GradleNotificationExtension implements ExternalSystemNotificationEx
   }
 
   protected void updateNotification(@NotNull final NotificationData notificationData,
-                                         @NotNull final Project project,
-                                         @NotNull ExternalSystemException e) {
-
+                                    @NotNull final Project project,
+                                    @NotNull ExternalSystemException e) {
+    if(e instanceof BuildIssueException) {
+      BuildIssue buildIssue = ((BuildIssueException)e).getBuildIssue();
+      for (BuildIssueQuickFix quickFix : buildIssue.getQuickFixes()) {
+        notificationData.setListener(quickFix.getId(), (notification, event) -> quickFix.runQuickFix(project));
+      }
+      return;
+    }
     for (String fix : e.getQuickFixes()) {
       if (OpenGradleSettingsCallback.ID.equals(fix)) {
         notificationData.setListener(OpenGradleSettingsCallback.ID, new OpenGradleSettingsCallback(project));
index bb480e35ab3ee2c292b37d685c2bce0c7f6f1776..6503f3524ffebc4efd8d24eb94c15f5a22766851 100644 (file)
@@ -17,6 +17,7 @@ package org.jetbrains.plugins.gradle.service.project;
 
 import com.intellij.openapi.externalSystem.model.ExternalSystemException;
 import com.intellij.openapi.util.Pair;
+import org.gradle.tooling.model.build.BuildEnvironment;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.gradle.service.execution.GradleExecutionErrorHandler;
@@ -36,7 +37,8 @@ public abstract class AbstractProjectImportErrorHandler {
   public static final String EMPTY_LINE = "\n\n";
 
   @Nullable
-  public abstract ExternalSystemException getUserFriendlyError(@NotNull Throwable error,
+  public abstract ExternalSystemException getUserFriendlyError(@Nullable BuildEnvironment buildEnvironment,
+                                                               @NotNull Throwable error,
                                                                @NotNull String projectPath,
                                                                @Nullable String buildFilePath);
 
index 60f023da6c234ed64ab61373dcd085fb43d1aba8..4e3af29011b3dd4186c5a03eab6667094ba1e8f4 100644 (file)
@@ -26,6 +26,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
 import com.intellij.openapi.externalSystem.util.Order;
 import com.intellij.openapi.util.Pair;
 import com.intellij.util.Consumer;
+import org.gradle.tooling.model.build.BuildEnvironment;
 import org.gradle.tooling.model.idea.IdeaModule;
 import org.gradle.tooling.model.idea.IdeaProject;
 import org.jetbrains.annotations.ApiStatus;
@@ -152,10 +153,11 @@ public abstract class AbstractProjectResolverExtension implements GradleProjectR
 
   @NotNull
   @Override
-  public ExternalSystemException getUserFriendlyError(@NotNull Throwable error,
+  public ExternalSystemException getUserFriendlyError(@Nullable BuildEnvironment buildEnvironment,
+                                                      @NotNull Throwable error,
                                                       @NotNull String projectPath,
                                                       @Nullable String buildFilePath) {
-    return nextResolver.getUserFriendlyError(error, projectPath, buildFilePath);
+    return nextResolver.getUserFriendlyError(buildEnvironment, error, projectPath, buildFilePath);
   }
 
   @Override
index 61ac340aa33f892993b104a1c7536352056f2fb6..dfbba2f0dc892ec26865f8f30a61b493e9371f44 100644 (file)
@@ -42,6 +42,7 @@ import org.gradle.tooling.model.DomainObjectSet;
 import org.gradle.tooling.model.GradleModuleVersion;
 import org.gradle.tooling.model.GradleTask;
 import org.gradle.tooling.model.UnsupportedMethodException;
+import org.gradle.tooling.model.build.BuildEnvironment;
 import org.gradle.tooling.model.gradle.GradleBuild;
 import org.gradle.tooling.model.idea.*;
 import org.gradle.util.GradleVersion;
@@ -806,10 +807,11 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
 
   @NotNull
   @Override
-  public ExternalSystemException getUserFriendlyError(@NotNull Throwable error,
+  public ExternalSystemException getUserFriendlyError(@Nullable BuildEnvironment buildEnvironment,
+                                                      @NotNull Throwable error,
                                                       @NotNull String projectPath,
                                                       @Nullable String buildFilePath) {
-    return myErrorHandler.getUserFriendlyError(error, projectPath, buildFilePath);
+    return myErrorHandler.getUserFriendlyError(buildEnvironment, error, projectPath, buildFilePath);
   }
 
   @Override
index 84f78d3e2ad90e11fc37caf5beccc8ae42c40657..68b4e8a5b7dc24a74291222cdd180cb5ca95fa96 100644 (file)
  */
 package org.jetbrains.plugins.gradle.service.project;
 
+import com.intellij.build.issue.BuildIssue;
+import com.intellij.build.issue.BuildIssueChecker;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.externalSystem.model.ExternalSystemException;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.ObjectUtils;
 import org.gradle.cli.CommandLineArgumentException;
 import org.gradle.tooling.UnsupportedVersionException;
+import org.gradle.tooling.model.build.BuildEnvironment;
+import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.issue.*;
 import org.jetbrains.plugins.gradle.service.execution.GradleExecutionErrorHandler;
 import org.jetbrains.plugins.gradle.service.notification.GotoSourceNotificationCallback;
 import org.jetbrains.plugins.gradle.service.notification.OpenGradleSettingsCallback;
@@ -34,6 +38,10 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.net.ConnectException;
 import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.intellij.util.ObjectUtils.notNull;
 
 /**
  * @author Vladislav.Soroka
@@ -44,18 +52,30 @@ public class BaseProjectImportErrorHandler extends AbstractProjectImportErrorHan
 
   @NotNull
   @Override
-  public ExternalSystemException getUserFriendlyError(@NotNull Throwable error,
+  public ExternalSystemException getUserFriendlyError(@Nullable BuildEnvironment buildEnvironment,
+                                                      @NotNull Throwable error,
                                                       @NotNull String projectPath,
                                                       @Nullable String buildFilePath) {
     GradleExecutionErrorHandler executionErrorHandler = new GradleExecutionErrorHandler(error, projectPath, buildFilePath);
-    ExternalSystemException exception = doGetUserFriendlyError(error, projectPath, buildFilePath, executionErrorHandler);
-    if (exception.getCause() == null) {
-      exception.initCause(ObjectUtils.notNull(executionErrorHandler.getRootCause(), error));
+    ExternalSystemException exception = doGetUserFriendlyError(buildEnvironment, error, projectPath, buildFilePath, executionErrorHandler);
+    if (!exception.isCauseInitialized()) {
+      exception.initCause(notNull(executionErrorHandler.getRootCause(), error));
     }
     return exception;
   }
 
-  private ExternalSystemException doGetUserFriendlyError(@NotNull Throwable error,
+  @ApiStatus.Experimental
+  ExternalSystemException checkErrorsWithoutQuickFixes(@Nullable BuildEnvironment buildEnvironment,
+                                                       @NotNull Throwable error,
+                                                       @NotNull String projectPath,
+                                                       @Nullable String buildFilePath,
+                                                       @NotNull ExternalSystemException e) {
+    if (e.getQuickFixes().length > 0 || e instanceof BuildIssueException) return e;
+    return getUserFriendlyError(buildEnvironment, error, projectPath, buildFilePath);
+  }
+
+  private ExternalSystemException doGetUserFriendlyError(@Nullable BuildEnvironment buildEnvironment,
+                                                         @NotNull Throwable error,
                                                          @NotNull String projectPath,
                                                          @Nullable String buildFilePath,
                                                          @NotNull GradleExecutionErrorHandler executionErrorHandler) {
@@ -64,7 +84,7 @@ public class BaseProjectImportErrorHandler extends AbstractProjectImportErrorHan
       return friendlyError;
     }
 
-    LOG.info(String.format("Failed to import Gradle project at '%1$s'", projectPath), error);
+    LOG.debug(String.format("Failed to run Gradle project at '%1$s'", projectPath), error);
 
     if (error instanceof ProcessCanceledException) {
       return new ExternalSystemException("Project build was cancelled");
index a4941bc71a1733f6319e5ad0b0541ef1404ee5bc..be741f079a6b4bee6e36cdf781997cd3a7a8965d 100644 (file)
@@ -49,6 +49,7 @@ public class DefaultProjectResolverContext extends UserDataHolderBase implements
   private File myGradleUserHome;
   @Nullable private String myProjectGradleVersion;
   @Nullable private String myBuildSrcGroup;
+  @Nullable private BuildEnvironment myBuildEnvironment;
 
   public DefaultProjectResolverContext(@NotNull final ExternalSystemTaskId externalSystemTaskId,
                                        @NotNull final String projectPath,
@@ -192,9 +193,11 @@ public class DefaultProjectResolverContext extends UserDataHolderBase implements
   @Override
   public String getProjectGradleVersion() {
     if (myProjectGradleVersion == null) {
-      final BuildEnvironment env = getModels().getBuildEnvironment();
-      if (env != null) {
-        myProjectGradleVersion = env.getGradle().getGradleVersion();
+      if (myBuildEnvironment == null) {
+        myBuildEnvironment = getModels().getBuildEnvironment();
+      }
+      if (myBuildEnvironment != null) {
+        myProjectGradleVersion = myBuildEnvironment.getGradle().getGradleVersion();
       }
     }
     return myProjectGradleVersion;
@@ -209,4 +212,13 @@ public class DefaultProjectResolverContext extends UserDataHolderBase implements
   public String getBuildSrcGroup() {
     return myBuildSrcGroup;
   }
+
+  void setBuildEnvironment(@NotNull BuildEnvironment buildEnvironment) {
+    myBuildEnvironment = buildEnvironment;
+  }
+
+  @Nullable
+  public BuildEnvironment getBuildEnvironment() {
+    return myBuildEnvironment;
+  }
 }
index dc757738bd12a3bb72c91d97a830f567d7d8608f..207b8676cf4791a7803ef4cc9f12f76ddd1917b3 100644 (file)
@@ -172,6 +172,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
       gradleVersion = GradleVersion.version(buildEnvironment.getGradle().getGradleVersion());
       isGradleProjectDirSupported = gradleVersion.compareTo(GradleVersion.version("2.4")) >= 0;
       isCompositeBuildsSupported = isGradleProjectDirSupported && gradleVersion.compareTo(GradleVersion.version("3.1")) >= 0;
+      resolverCtx.setBuildEnvironment(buildEnvironment);
     }
     final ProjectImportAction projectImportAction =
       new ProjectImportAction(resolverCtx.isPreviewMode(), isGradleProjectDirSupported, isCompositeBuildsSupported);
@@ -723,11 +724,8 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
       }
       catch (RuntimeException e) {
         LOG.info("Gradle project resolve error", e);
-        ExternalSystemException exception = myProjectResolverChain.getUserFriendlyError(e, myResolverContext.getProjectPath(), null);
-        if (exception.getCause() == null) {
-          exception.initCause(e);
-        }
-        throw exception;
+        throw myProjectResolverChain.getUserFriendlyError(
+          myResolverContext.getBuildEnvironment(), e, myResolverContext.getProjectPath(), null);
       }
       finally {
         myCancellationMap.remove(myResolverContext.getExternalSystemTaskId(), myResolverContext.getCancellationTokenSource());
@@ -737,7 +735,6 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
 
   @NotNull
   public static GradleProjectResolverExtension createProjectResolverChain(@Nullable final GradleExecutionSettings settings) {
-    GradleProjectResolverExtension projectResolverChain;
     if (settings != null) {
       List<ClassHolder<? extends GradleProjectResolverExtension>> extensionClasses = settings.getResolverExtensions();
       if(extensionClasses.isEmpty()) {
@@ -762,9 +759,8 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
         }
         extensions.add(extension);
       }
-      projectResolverChain = extensions.peekFirst();
-
-      GradleProjectResolverExtension resolverExtension = projectResolverChain;
+      GradleProjectResolverExtension firstResolver = extensions.peekFirst();
+      GradleProjectResolverExtension resolverExtension = firstResolver;
       assert resolverExtension != null;
       while (resolverExtension.getNext() != null) {
         resolverExtension = resolverExtension.getNext();
@@ -772,11 +768,23 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
       if (!(resolverExtension instanceof BaseGradleProjectResolverExtension)) {
         throw new AssertionError("Illegal last resolver got of class " + resolverExtension.getClass().getName());
       }
+      BaseProjectImportErrorHandler baseErrorHandler = new BaseProjectImportErrorHandler();
+      GradleProjectResolverExtension chainWrapper = new AbstractProjectResolverExtension() {
+        @NotNull
+        @Override
+        public ExternalSystemException getUserFriendlyError(@Nullable BuildEnvironment buildEnvironment,
+                                                            @NotNull Throwable error,
+                                                            @NotNull String projectPath,
+                                                            @Nullable String buildFilePath) {
+          ExternalSystemException friendlyError = super.getUserFriendlyError(buildEnvironment, error, projectPath, buildFilePath);
+          return baseErrorHandler.checkErrorsWithoutQuickFixes(buildEnvironment, error, projectPath, buildFilePath, friendlyError);
+        }
+      };
+      chainWrapper.setNext(firstResolver);
+      return chainWrapper;
     }
     else {
-      projectResolverChain = new BaseGradleProjectResolverExtension();
+      return new BaseGradleProjectResolverExtension();
     }
-
-    return projectResolverChain;
   }
 }
index b6c50f4e42bd0fdbf876e1f936f6730e1c177362..dc5f8089f9b586548c61f97a81c396fe4724498e 100644 (file)
@@ -25,6 +25,7 @@ import com.intellij.openapi.externalSystem.model.task.TaskData;
 import com.intellij.openapi.externalSystem.service.ParametersEnhancer;
 import com.intellij.openapi.util.Pair;
 import com.intellij.util.Consumer;
+import org.gradle.tooling.model.build.BuildEnvironment;
 import org.gradle.tooling.model.idea.IdeaModule;
 import org.gradle.tooling.model.idea.IdeaProject;
 import org.jetbrains.annotations.ApiStatus;
@@ -123,7 +124,10 @@ public interface GradleProjectResolverExtension extends ParametersEnhancer {
   List<String> getExtraCommandLineArgs();
 
   @NotNull
-  ExternalSystemException getUserFriendlyError(@NotNull Throwable error, @NotNull String projectPath, @Nullable String buildFilePath);
+  ExternalSystemException getUserFriendlyError(@Nullable BuildEnvironment buildEnvironment,
+                                               @NotNull Throwable error,
+                                               @NotNull String projectPath,
+                                               @Nullable String buildFilePath);
 
   /**
    * Performs project configuration and other checks before the actual project import (before invocation of gradle tooling API).
index 6d1435278e456960384d9b253333a12f56bf015f..0f8050a2f4ba54e9517ca80b1d87f2d23287f355 100644 (file)
@@ -19,6 +19,7 @@ import org.gradle.tooling.BuildLauncher;
 import org.gradle.tooling.CancellationTokenSource;
 import org.gradle.tooling.GradleConnector;
 import org.gradle.tooling.ProjectConnection;
+import org.gradle.tooling.model.build.BuildEnvironment;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper;
@@ -115,12 +116,9 @@ public class GradleTaskManager extends BaseExternalSystemTaskManager<GradleExecu
       }
       catch (RuntimeException e) {
         LOG.debug("Gradle build launcher error", e);
+        BuildEnvironment buildEnvironment = GradleExecutionHelper.getBuildEnvironment(connection, id, listener, cancellationTokenSource);
         final GradleProjectResolverExtension projectResolverChain = GradleProjectResolver.createProjectResolverChain(effectiveSettings);
-        ExternalSystemException exception = projectResolverChain.getUserFriendlyError(e, projectPath, null);
-        if(exception.getCause() == null) {
-          exception.initCause(e);
-        }
-        throw exception;
+        throw projectResolverChain.getUserFriendlyError(buildEnvironment, e, projectPath, null);
       }
     };
     if (effectiveSettings.getDistributionType() == DistributionType.WRAPPED) {
index 454bc97df80d0635dbc2a56bc5597a34813d49d8..88dfef8432d5301cffe7e9184e7e31d1030bd633 100644 (file)
@@ -53,7 +53,7 @@ public class BaseProjectImportErrorHandlerTest {
 
     Throwable error = new Throwable(locationError);
 
-    RuntimeException realCause = myErrorHandler.getUserFriendlyError(error, myProjectPath, null);
+    RuntimeException realCause = myErrorHandler.getUserFriendlyError(null, error, myProjectPath, null);
     assertTrue(realCause instanceof LocationAwareExternalSystemException);
     LocationAwareExternalSystemException locationAwareExternalSystemException = (LocationAwareExternalSystemException)realCause;
     assertEquals("~/project/build.gradle", locationAwareExternalSystemException.getFilePath());
@@ -66,7 +66,7 @@ public class BaseProjectImportErrorHandlerTest {
     String causeMsg = "com.mypackage.MyImaginaryClass";
     ClassNotFoundException rootCause = new ClassNotFoundException(causeMsg);
     Throwable error = new Throwable(rootCause);
-    RuntimeException realCause = myErrorHandler.getUserFriendlyError(error, myProjectPath, null);
+    RuntimeException realCause = myErrorHandler.getUserFriendlyError(null, error, myProjectPath, null);
     assertTrue(realCause.getMessage().contains("Unable to load class 'com.mypackage.MyImaginaryClass'."));
   }
 }