-
- Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
I've checked docs and closed issues for possible solutions.
I can't find my issue in the FAQ.
Describe the issue
When using Rich to render tracebacks in a VSCode Remote SSH development environment, the clickable file links in the traceback output point to the local filesystem path (e.g., file:///home/user/...) instead of the correct VSCode Remote SSH URI (e.g., vscode-remote://ssh-remote+server-name/home/user/...).
This causes VSCode to attempt opening the file on the local machine (which does not exist), resulting in a "System cannot find the file specified (0x2)" error, instead of navigating to the corresponding file on the remote server.
To Reproduce
- Set up a VSCode Remote SSH connection to an Ubuntu 20.04 server.
- In the remote environment, install
rich==14.3.3andPython 3.12.11. - Run a Python script that triggers an uncaught exception, with Rich's traceback handler installed:
from rich.traceback import install install(show_locals=True) # Trigger an exception 1 / 0
- Observe the traceback output in the VSCode terminal.
- Click on any file path link (e.g.,
test.py:5).
Expected behavior: The link opens the file at the correct line number in the VSCode Remote SSH window (pointing to the server's filesystem).
Actual behavior: VSCode attempts to open the path on the local machine, failing with a file not found error.
Screenshots
(Shows the "Failed to open: 系统找不到指定的文件。(0x2)" dialog after clicking a traceback link)
Platform
- rich==14.3.3
- Python==3.12.11
- OS: Ubuntu 20.04.6 LTS (Server, accessed via VSCode Remote SSH)
- VSCode Version: 1.107.1
- Local OS: Windows 11 (client machine)
Additional context
- The issue occurs specifically in the VSCode Remote SSH context. Running the same code locally works correctly (links point to the local filesystem).
- VSCode injects the
VSCODE_REMOTE_NAMEenvironment variable into the remote shell, which contains the server alias (e.g.,my-server). A correct remote URI would bevscode-remote://ssh-remote+{VSCODE_REMOTE_NAME}{absolute_file_path}#L{line_number}. - The current implementation of
rich.tracebackgenerates onlyfile://links, which do not respect the VSCode Remote environment.
Possible root cause
The rich.traceback module's path formatting logic does not detect the VSCode Remote SSH environment and does not generate the vscode-remote:// protocol links required for correct file navigation in this setup.
P.S. This is my logging.py file。 I would be pleased to provide any additional information or assistance you might need. Thank you for your time and consideration. I appreciate any feedback you can provide.
import logging from datetime import datetime from rich.theme import Theme from rich.console import Console from rich.logging import RichHandler custom_theme = Theme( { "info": "cyan", "warning": "yellow", "error": "bold red", "critical": "bold white on red", "debug": "dim cyan", "success": "bold green", } ) def setup_logger( name: str = None, level: str = "INFO", log_file: str = None, rich_tracebacks: bool = True, ) -> logging.Logger: logger = logging.getLogger(name) logger.setLevel(getattr(logging, level.upper())) if logger.handlers: return logger console_handler = RichHandler( console=Console(theme=custom_theme), rich_tracebacks=rich_tracebacks, tracebacks_show_locals=True, show_time=True, show_path=True, markup=True, ) console_handler.setLevel(getattr(logging, level.upper())) logger.addHandler(console_handler) if log_file: import os os.makedirs(os.path.dirname(log_file) or ".", exist_ok=True) file_handler = logging.FileHandler(log_file, encoding="utf-8") file_handler.setLevel(getattr(logging, level.upper())) file_formatter = logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) file_handler.setFormatter(file_formatter) logger.addHandler(file_handler) return logger def get_logger(name: str = None) -> logging.Logger: return logging.getLogger(name) def setup_experiment_logger( experiment_name: str, log_dir: str = "./logs", level: str = "INFO" ) -> logging.Logger: log_file = ( f"{log_dir}/{experiment_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log" ) return setup_logger(experiment_name, level, log_file)