diff --git a/spyder/plugins/ipythonconsole/__init__.py b/spyder/plugins/ipythonconsole/__init__.py
index 2ff34ccd29d..de5cf9b96d7 100644
--- a/spyder/plugins/ipythonconsole/__init__.py
+++ b/spyder/plugins/ipythonconsole/__init__.py
@@ -44,5 +44,12 @@
class SpyderKernelError(RuntimeError):
- """Error to be shown in client."""
- pass
+ """
+ Error to be shown in the IPython console.
+
+ Notes
+ -----
+ * Use this exception if you want to show a nice formatted error in the
+ current console instead of a long and hard-to-read traceback.
+ * This should only be used for errors whose cause we are certain of.
+ """
diff --git a/spyder/plugins/ipythonconsole/utils/client.py b/spyder/plugins/ipythonconsole/utils/client.py
index 7f10a69bc5d..57fa71e2bf7 100644
--- a/spyder/plugins/ipythonconsole/utils/client.py
+++ b/spyder/plugins/ipythonconsole/utils/client.py
@@ -20,6 +20,7 @@
# Local imports
from spyder.api.asyncdispatcher import AsyncDispatcher
from spyder.api.translations import _
+from spyder.plugins.ipythonconsole import SpyderKernelError
class KernelClientTunneler:
@@ -63,10 +64,10 @@ async def forward_port(self, remote_host, remote_port):
)
)
except asyncssh.Error as err:
- raise RuntimeError(
+ raise SpyderKernelError(
_(
- "It was not possible to open an SSH tunnel for the "
- "remote kernel. Please check your credentials and the "
+ "It was not possible to open an SSH tunnel to connect to "
+ "the remote kernel. Please check your credentials and the "
"server connection status."
)
) from err
diff --git a/spyder/plugins/ipythonconsole/utils/kernel_handler.py b/spyder/plugins/ipythonconsole/utils/kernel_handler.py
index 10dada739d9..b8a9f73f305 100644
--- a/spyder/plugins/ipythonconsole/utils/kernel_handler.py
+++ b/spyder/plugins/ipythonconsole/utils/kernel_handler.py
@@ -27,6 +27,7 @@
SPYDER_KERNELS_VERSION,
SPYDER_KERNELS_CONDA,
SPYDER_KERNELS_PIP,
+ SpyderKernelError,
)
from spyder.plugins.ipythonconsole.comms.kernelcomm import KernelComm
from spyder.plugins.ipythonconsole.utils.manager import SpyderKernelManager
@@ -35,8 +36,8 @@
PERMISSION_ERROR_MSG = _(
- "The directory {} is not writable and it is required to create IPython "
- "consoles. Please make it writable."
+ "The directory {} is not writable and it is required to create "
+ "IPython consoles. Please make it writable."
)
ERROR_SPYDER_KERNEL_VERSION = _(
@@ -377,7 +378,7 @@ def new_from_spec(cls, kernel_spec):
"""
connection_file = cls.new_connection_file()
if connection_file is None:
- raise RuntimeError(
+ raise SpyderKernelError(
PERMISSION_ERROR_MSG.format(jupyter_runtime_dir())
)
@@ -390,11 +391,19 @@ def new_from_spec(cls, kernel_spec):
kernel_manager._kernel_spec = kernel_spec
- kernel_manager.start_kernel(
- stderr=PIPE,
- stdout=PIPE,
- env=kernel_spec.env,
- )
+ try:
+ kernel_manager.start_kernel(
+ stderr=PIPE,
+ stdout=PIPE,
+ env=kernel_spec.env,
+ )
+ except PermissionError:
+ # Show a nice error message when jupyter_runtime_dir is not
+ # writable.
+ # Fixes spyder-ide/spyder#23124
+ raise SpyderKernelError(
+ PERMISSION_ERROR_MSG.format(jupyter_runtime_dir())
+ )
# Kernel client
kernel_client = kernel_manager.client()
@@ -474,13 +483,13 @@ def init_kernel_client(
try:
kernel_client.load_connection_file()
except Exception as e:
- raise RuntimeError(
+ raise SpyderKernelError(
_(
"An error occurred while trying to load "
"the kernel connection file. The error "
"was:\n\n"
)
- + str(e)
+ + f"{str(e)}"
)
if hostname is not None or ssh_connection is not None: