mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1750153 - Prevent unwanted errors from showing up in ./mach show-log
after closing less
before the entire log file has been piped to it r=firefox-build-system-reviewers,mhentges
The main thread is blocking (for an unknown reason) without piping the entirety of the log file to `less` (unless the user manually scrolls to almost the bottom). Since the piping cannot always complete without a user terminating, we must hide the errors that arise from using the `stdin` stream for the `less` process after the process is terminated. Differential Revision: https://phabricator.services.mozilla.com/D135979
This commit is contained in:
parent
5b1ec638ce
commit
bea764be73
@ -17,6 +17,7 @@ import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import errno
|
||||
|
||||
import mozbuild.settings # noqa need @SettingsProvider hook to execute
|
||||
import mozpack.path as mozpath
|
||||
@ -361,31 +362,60 @@ def show_log(command_context, log_file=None):
|
||||
["less"], stdin=subprocess.PIPE, env=env, encoding="UTF-8"
|
||||
)
|
||||
|
||||
# Create a new logger handler with the stream being the stdin of our 'less'
|
||||
# process so that we can pipe the logger output into 'less'
|
||||
less_handler = logging.StreamHandler(stream=less.stdin)
|
||||
less_handler.setFormatter(
|
||||
command_context.log_manager.terminal_handler.formatter
|
||||
)
|
||||
less_handler.setLevel(command_context.log_manager.terminal_handler.level)
|
||||
try:
|
||||
# Create a new logger handler with the stream being the stdin of our 'less'
|
||||
# process so that we can pipe the logger output into 'less'
|
||||
less_handler = logging.StreamHandler(stream=less.stdin)
|
||||
less_handler.setFormatter(
|
||||
command_context.log_manager.terminal_handler.formatter
|
||||
)
|
||||
less_handler.setLevel(command_context.log_manager.terminal_handler.level)
|
||||
|
||||
# replace the existing terminal handler with the new one for 'less' while
|
||||
# still keeping the original one to set back later
|
||||
original_handler = command_context.log_manager.replace_terminal_handler(
|
||||
less_handler
|
||||
)
|
||||
# replace the existing terminal handler with the new one for 'less' while
|
||||
# still keeping the original one to set back later
|
||||
original_handler = command_context.log_manager.replace_terminal_handler(
|
||||
less_handler
|
||||
)
|
||||
|
||||
# Parses the log file line by line and streams (to less.stdin) the relevant records we want
|
||||
handle_log_file(command_context, log_file)
|
||||
# Save this value so we can set it back to the original value later
|
||||
original_logging_raise_exceptions = logging.raiseExceptions
|
||||
|
||||
# Set the handler (and contained stream) back to the original one
|
||||
command_context.log_manager.replace_terminal_handler(original_handler)
|
||||
# We need to explicitly disable raising exceptions inside logging so
|
||||
# that we can catch them here ourselves to ignore the ones we want
|
||||
logging.raiseExceptions = False
|
||||
|
||||
# At this point we've piped the entire log file to 'less', so we can close the input stream
|
||||
less.stdin.close()
|
||||
# Wait for the user to manually terminate `less`
|
||||
less.wait()
|
||||
# Parses the log file line by line and streams
|
||||
# (to less.stdin) the relevant records we want
|
||||
handle_log_file(command_context, log_file)
|
||||
|
||||
# At this point we've piped the entire log file to
|
||||
# 'less', so we can close the input stream
|
||||
less.stdin.close()
|
||||
|
||||
# Wait for the user to manually terminate `less`
|
||||
less.wait()
|
||||
except OSError as os_error:
|
||||
# (POSIX) errno.EPIPE: BrokenPipeError: [Errno 32] Broken pipe
|
||||
# (Windows) errno.EINVAL: OSError: [Errno 22] Invalid argument
|
||||
if os_error.errno == errno.EPIPE or os_error.errno == errno.EINVAL:
|
||||
# If the user manually terminates 'less' before the entire log file
|
||||
# is piped (without scrolling close enough to the bottom) we will get
|
||||
# one of these errors (depends on the OS) because the logger will still
|
||||
# attempt to stream to the now invalid less.stdin. To prevent a bunch
|
||||
# of errors being shown after a user terminates 'less', we just catch
|
||||
# the first of those exceptions here, and stop parsing the log file.
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
except Exception:
|
||||
raise
|
||||
finally:
|
||||
# Ensure these values are changed back to the originals, regardless of outcome
|
||||
command_context.log_manager.replace_terminal_handler(original_handler)
|
||||
logging.raiseExceptions = original_logging_raise_exceptions
|
||||
else:
|
||||
# Not in a terminal context, so just handle the log file with the
|
||||
# default stream without piping it to a pager (less)
|
||||
handle_log_file(command_context, log_file)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user