From e6272666adc040b52f1d777eaebfc1884731ec3e Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Sat, 11 Nov 2017 00:59:50 +0300 Subject: [PATCH] PY-26942: Check SDK for null * SDK may be null or something else may lead to framework installation failure. * SDK is checked for null and error reported by new method that should be used to report any installation failures --- .../newProject/PyNewProjectSettings.java | 5 ++- .../newProject/PythonProjectGenerator.java | 43 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/python/openapi/src/com/jetbrains/python/newProject/PyNewProjectSettings.java b/python/openapi/src/com/jetbrains/python/newProject/PyNewProjectSettings.java index d71197da1497..105d6f7ecb7d 100644 --- a/python/openapi/src/com/jetbrains/python/newProject/PyNewProjectSettings.java +++ b/python/openapi/src/com/jetbrains/python/newProject/PyNewProjectSettings.java @@ -32,11 +32,12 @@ public class PyNewProjectSettings { @Nullable private String myRemotePath; - public Sdk getSdk() { + @Nullable + public final Sdk getSdk() { return mySdk; } - public void setSdk(Sdk sdk) { + public final void setSdk(@Nullable final Sdk sdk) { mySdk = sdk; } diff --git a/python/src/com/jetbrains/python/newProject/PythonProjectGenerator.java b/python/src/com/jetbrains/python/newProject/PythonProjectGenerator.java index 0c271105b26c..36ea2aa46dd7 100644 --- a/python/src/com/jetbrains/python/newProject/PythonProjectGenerator.java +++ b/python/src/com/jetbrains/python/newProject/PythonProjectGenerator.java @@ -15,18 +15,26 @@ */ package com.jetbrains.python.newProject; +import com.intellij.execution.ExecutionException; import com.intellij.facet.ui.ValidationResult; import com.intellij.icons.AllIcons.General; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.platform.DirectoryProjectGeneratorBase; import com.intellij.util.BooleanFunction; import com.intellij.util.containers.ContainerUtil; +import com.intellij.webcore.packaging.PackageManagementService.ErrorDescription; +import com.intellij.webcore.packaging.PackagesNotificationPanel; +import com.jetbrains.python.packaging.ui.PyPackageManagementService; import com.jetbrains.python.remote.*; import com.jetbrains.python.sdk.PyLazySdk; import com.jetbrains.python.sdk.PySdkUtil; @@ -37,6 +45,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.MouseListener; import java.io.File; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -61,11 +70,16 @@ import java.util.function.Consumer; * * *

+ *

How to report framework installation failures

+ *

{@link PyNewProjectSettings#getSdk()} may return null, or something else may prevent package installation. + * Use {@link #reportPackageInstallationFailure(String, Pair)} in this case. + *

* * @param project settings */ public abstract class PythonProjectGenerator extends DirectoryProjectGeneratorBase { public static final PyNewProjectSettings NO_SETTINGS = new PyNewProjectSettings(); + private static final Logger LOGGER = Logger.getInstance(PythonProjectGenerator.class); private final List myListeners = ContainerUtil.newArrayList(); private final boolean myAllowRemoteProjectCreation; @@ -278,8 +292,37 @@ public abstract class PythonProjectGenerator ext public void createAndAddVirtualEnv(Project project, PyNewProjectSettings settings) { } + /** + * @param sdkAndException if you have SDK and execution exception provide them here (both must not be null). + */ + protected static void reportPackageInstallationFailure(@NotNull final String frameworkName, + @Nullable final Pair sdkAndException) { + + final ErrorDescription errorDescription = getErrorDescription(sdkAndException); + final Application app = ApplicationManager.getApplication(); + app.invokeLater(() -> PackagesNotificationPanel.showError(String.format("Install %s failed", frameworkName), errorDescription)); + } + + @NotNull + private static ErrorDescription getErrorDescription(@Nullable final Pair sdkAndException) { + ErrorDescription errorDescription = null; + if (sdkAndException != null) { + final ExecutionException exception = sdkAndException.second; + errorDescription = PyPackageManagementService.toErrorDescription(Collections.singletonList(exception), sdkAndException.first); + if (errorDescription == null) { + errorDescription = ErrorDescription.fromMessage(exception.getMessage()); + } + } + + if (errorDescription == null) { + errorDescription = ErrorDescription.fromMessage("Choose another SDK"); + } + return errorDescription; + } + /** * To be thrown if project can't be created on this sdk + * * @author Ilya.Kazakevich */ public static class PyNoProjectAllowedOnSdkException extends Exception {