Skip to content

Commit 8902834

Browse files
print stacktraces during import errors
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
1 parent 923f461 commit 8902834

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

src/python/pants/base/exception_sink.py

+28-6
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,22 @@ class ExceptionSink:
110110
# Where to log stacktraces to in a SIGUSR2 handler.
111111
_interactive_output_stream = None
112112

113-
# An instance of `SignalHandler` which is invoked to handle a static set of specific
114-
# nonfatal signals (these signal handlers are allowed to make pants exit, but unlike SIGSEGV they
115-
# don't need to exit immediately).
113+
# An instance of `SignalHandler` which is invoked to handle a static set of specific nonfatal
114+
# signals (these signal handlers are allowed to make pants exit, but unlike SIGSEGV they don't
115+
# need to exit immediately).
116116
_signal_handler: SignalHandler = SignalHandler(pantsd_instance=False)
117117

118118
# These persistent open file descriptors are kept so the signal handler can do almost no work
119119
# (and lets faulthandler figure out signal safety).
120120
_pid_specific_error_fileobj = None
121121
_shared_error_fileobj = None
122122

123+
# Set in methods on SignalHandler and exposed to the engine rust code.
123124
_signal_sent: Optional[int] = None
124125

126+
# Whether the rust logger has been initialized so we can stop doing extra work in this class.
127+
_logging_initialized: bool = False
128+
125129
def __new__(cls, *args, **kwargs):
126130
raise TypeError("Instances of {} are not allowed to be constructed!".format(cls.__name__))
127131

@@ -188,6 +192,16 @@ def reset_log_location(cls, new_log_location: str) -> None:
188192
cls._pid_specific_error_fileobj = pid_specific_error_stream
189193
cls._shared_error_fileobj = shared_error_stream
190194

195+
@classmethod
196+
def set_logging_initialized(cls):
197+
"""Set the flag (to True) which indicates that the rust logger has been initialized.
198+
199+
Class state:
200+
- Overwrites `cls._logging_initialized`.
201+
"""
202+
# NB: mutate the class variables!
203+
cls._logging_initialized = True
204+
191205
@classmethod
192206
def exceptions_log_path(cls, for_pid=None, in_dir=None):
193207
"""Get the path to either the shared or pid-specific fatal errors log file."""
@@ -360,7 +374,8 @@ def log_exception(cls, exc_class=None, exc=None, tb=None, add_newline=False):
360374

361375
extra_err_msg = None
362376
try:
363-
# Always output the unhandled exception details into a log file, including the traceback.
377+
# Always output the unhandled exception details into a log file, including the
378+
# traceback.
364379
exception_log_entry = cls._format_unhandled_exception_log(
365380
exc, tb, add_newline, should_print_backtrace=True
366381
)
@@ -369,8 +384,15 @@ def log_exception(cls, exc_class=None, exc=None, tb=None, add_newline=False):
369384
extra_err_msg = "Additional error logging unhandled exception {}: {}".format(exc, e)
370385
logger.error(extra_err_msg)
371386

372-
# Generate an unhandled exception report fit to be printed to the terminal.
373-
logger.exception(exc)
387+
# The rust logger implementation is used for most of pants's execution, but at import time,
388+
# we want to be able to see any stacktrace to know where the error is being raised.
389+
if cls._logging_initialized:
390+
logger.exception(exc)
391+
else:
392+
exception_log_entry = cls._format_unhandled_exception_log(
393+
exc, tb, add_newline, should_print_backtrace=True
394+
)
395+
logger.error(exception_log_entry)
374396

375397
@classmethod
376398
def _handle_signal_gracefully(cls, signum, signame, traceback_lines):

src/python/pants/bin/pants_runner.py

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def run(self, start_time: float) -> ExitCode:
7575
# We enable logging here, and everything before it will be routed through regular
7676
# Python logging.
7777
setup_logging(global_bootstrap_options, stderr_logging=True)
78+
ExceptionSink.set_logging_initialized()
7879

7980
if self._should_run_with_pantsd(global_bootstrap_options):
8081
try:

0 commit comments

Comments
 (0)