# Buggy code
def run(self):
    if not sys.stdout.isatty():
        print(
            "Error: mitmproxy's console interface requires a tty. "
            "Please run mitmproxy in an interactive shell environment.",
            file=sys.stderr,
        )
        sys.exit(1)

    self.ui = window.Screen()
    self.ui.set_terminal_properties(256)
    self.set_palette(self.options, None)
    self.options.subscribe(
        self.set_palette, ["console_palette", "console_palette_transparent"]
    )
    self.loop = urwid.MainLoop(
        urwid.SolidFill("x"),
        event_loop=urwid.AsyncioEventLoop(loop=asyncio.get_event_loop()),
        screen=self.ui,
        handle_mouse=self.options.console_mouse,
    )
    self.window = window.Window(self)
    self.loop.widget = self.window
    self.window.refresh()

    if self.start_err:

        def display_err(*_):
            self.sig_add_log(None, self.start_err)
            self.start_err = None

        self.loop.set_alarm_in(0.01, display_err)

    super().run_loop(self.loop.run)


# Traceback (ValueError)
Traceback (most recent call last):
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/master.py", line 56, in run_loop
loop()
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/main_loop.py", line 287, in run
self._run()
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/main_loop.py", line 385, in _run
self.event_loop.run()
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/main_loop.py", line 1494, in run
reraise(*exc_info)
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/compat.py", line 58, in reraise
raise value
File "/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/raw_display.py", line 416, in <lambda>
wrapper = lambda: self.parse_input(
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/raw_display.py", line 515, in parse_input
callback(processed, processed_codes)
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/main_loop.py", line 412, in _update
self.process_input(keys)
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/main_loop.py", line 513, in process_input
k = self._topmost_widget.keypress(self.screen_size, k)
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/tools/console/window.py", line 310, in keypress
k = super().keypress(size, k)
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/container.py", line 1135, in keypress
return self.body.keypress( (maxcol, remaining), key )
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/tools/console/window.py", line 44, in keypress
ret = super().keypress(size, key)
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/container.py", line 1135, in keypress
return self.body.keypress( (maxcol, remaining), key )
File "/Users/alex/work/code/python/mitmproxy/venv/lib/python3.9/site-packages/urwid/container.py", line 1135, in keypress
return self.body.keypress( (maxcol, remaining), key )
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/tools/console/tabs.py", line 41, in keypress
self.change_tab((self.tab_offset + 1) % n)
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/tools/console/tabs.py", line 34, in change_tab
self.show()
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/tools/console/tabs.py", line 73, in show
body = self.tabs[self.tab_offset % len(self.tabs)][1](),
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/tools/console/flowview.py", line 176, in view_details
return flowdetailview.flowdetails(self.view, self.flow)
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/tools/console/flowdetailview.py", line 72, in flowdetails
parts.append(("Alt names", ", ".join(strutils.bytes_to_escaped_str(x) for x in c.altnames)))
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/tools/console/flowdetailview.py", line 72, in <genexpr>
parts.append(("Alt names", ", ".join(strutils.bytes_to_escaped_str(x) for x in c.altnames)))
File "/Users/alex/work/code/python/mitmproxy/mitmproxy/utils/strutils.py", line 95, in bytes_to_escaped_str
raise ValueError(f"data must be bytes, but is {data.__class__.__name__}")
ValueError: data must be bytes, but is str

mitmproxy has crashed!

# Fixed code
def run(self):
    if not sys.stdout.isatty():
        print(
            "Error: mitmproxy's console interface requires a tty. "
            "Please run mitmproxy in an interactive shell environment.",
            file=sys.stderr,
        )
        sys.exit(1)

    signals.call_in.connect(self.sig_call_in)
    self.ui = window.Screen()
    self.ui.set_terminal_properties(256)
    self.set_palette(self.options, None)
    self.options.subscribe(
        self.set_palette, ["console_palette", "console_palette_transparent"]
    )
    self.loop = urwid.MainLoop(
        urwid.SolidFill("x"),
        event_loop=urwid.AsyncioEventLoop(loop=asyncio.get_event_loop()),
        screen=self.ui,
        handle_mouse=self.options.console_mouse,
    )
    self.window = window.Window(self)
    self.loop.widget = self.window
    self.window.refresh()

    if self.start_err:

        def display_err(*_):
            self.sig_add_log(None, self.start_err)
            self.start_err = None

        self.loop.set_alarm_in(0.01, display_err)

    super().run_loop(self.loop.run)