From b8bed1d7705d853f3c949bb4a4930a5390e9cfcd Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Tue, 29 Mar 2022 15:26:46 +0200 Subject: [PATCH] errorcheck: print message to stderr for console UI (#5225) --- CHANGELOG.md | 2 ++ mitmproxy/addons/errorcheck.py | 17 ++++++++++++----- mitmproxy/tools/console/master.py | 2 +- test/mitmproxy/addons/test_errorcheck.py | 8 ++++++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb5d8293c..7b3084697 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ ([#5190](https://github.com/mitmproxy/mitmproxy/issues/5190), @redraw) * Fix a bug where the wrong SNI is sent to an upstream HTTPS proxy ([#5109](https://github.com/mitmproxy/mitmproxy/issues/5109), @mhils) +* Make sure that mitmproxy displays error messages on startup. + ([#5225](https://github.com/mitmproxy/mitmproxy/issues/5225), @mhils) ## 19 March 2022: mitmproxy 8.0.0 diff --git a/mitmproxy/addons/errorcheck.py b/mitmproxy/addons/errorcheck.py index b522c9e39..4143a172c 100644 --- a/mitmproxy/addons/errorcheck.py +++ b/mitmproxy/addons/errorcheck.py @@ -1,15 +1,20 @@ import asyncio import sys +from typing import Optional + +from mitmproxy import log class ErrorCheck: """Monitor startup for error log entries, and terminate immediately if there are some.""" - def __init__(self): - self.has_errored = False - def add_log(self, e): - if e.level == "error": - self.has_errored = True + def __init__(self, log_to_stderr: bool = False): + self.has_errored: Optional[str] = None + self.log_to_stderr = log_to_stderr + + def add_log(self, e: log.LogEntry): + if not self.has_errored and e.level == "error": + self.has_errored = e.msg async def running(self): # don't run immediately, wait for all logging tasks to finish. @@ -17,4 +22,6 @@ class ErrorCheck: async def _shutdown_if_errored(self): if self.has_errored: + if self.log_to_stderr: + print(f"Error on startup: {self.has_errored}", file=sys.stderr) sys.exit(1) diff --git a/mitmproxy/tools/console/master.py b/mitmproxy/tools/console/master.py index 2fc286061..ca29d1c2a 100644 --- a/mitmproxy/tools/console/master.py +++ b/mitmproxy/tools/console/master.py @@ -56,7 +56,7 @@ class ConsoleMaster(master.Master): readfile.ReadFile(), consoleaddons.ConsoleAddon(self), keymap.KeymapConfig(), - errorcheck.ErrorCheck(), + errorcheck.ErrorCheck(log_to_stderr=True), ) self.window = None diff --git a/test/mitmproxy/addons/test_errorcheck.py b/test/mitmproxy/addons/test_errorcheck.py index e1cdd9f2a..17d3f12e0 100644 --- a/test/mitmproxy/addons/test_errorcheck.py +++ b/test/mitmproxy/addons/test_errorcheck.py @@ -6,11 +6,12 @@ from mitmproxy import log from mitmproxy.addons.errorcheck import ErrorCheck -def test_errorcheck(): +@pytest.mark.parametrize("do_log", [True, False]) +def test_errorcheck(capsys, do_log): async def run(): # suppress error that task exception was not retrieved. asyncio.get_running_loop().set_exception_handler(lambda *_: 0) - e = ErrorCheck() + e = ErrorCheck(do_log) e.add_log(log.LogEntry("fatal", "error")) await e.running() await asyncio.sleep(0) @@ -18,6 +19,9 @@ def test_errorcheck(): with pytest.raises(SystemExit): asyncio.run(run()) + if do_log: + assert capsys.readouterr().err == "Error on startup: fatal\n" + async def test_no_error(): e = ErrorCheck()