Skip to content

Commit 08b49b1

Browse files
rndusrRandom User
andauthored
LinuxDriver: Exit if thread dies (#3431)
* LinuxDriver: Exit if thread dies If `run_input_thread()` dies, the whole application keeps running but becomes unresponsive. It has to be killed by the user, leaving the terminal in an unusable state. This commit terminates the application instead and prints a traceback. * LinuxDriver: Handle any exception from input thread * LinuxDriver: Simpler traceback construction in input thread handler * LinuxDriver: Catch exception from run_input_thread() in _run_input_thread() * LinuxDriver: Remove unneeded import: Callable --------- Co-authored-by: Random User <[email protected]>
1 parent e1c3800 commit 08b49b1

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/textual/drivers/linux_driver.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from typing import TYPE_CHECKING, Any
1313

1414
import rich.repr
15+
import rich.traceback
1516

1617
from .. import events, log
1718
from .._xterm_parser import XTermParser
@@ -164,7 +165,7 @@ def on_terminal_resize(signum, stack) -> None:
164165
self.write("\x1b[?25l") # Hide cursor
165166
self.write("\033[?1003h\n")
166167
self.flush()
167-
self._key_thread = Thread(target=self.run_input_thread)
168+
self._key_thread = Thread(target=self._run_input_thread)
168169
send_size_event()
169170
self._key_thread.start()
170171
self._request_terminal_sync_mode_support()
@@ -233,6 +234,19 @@ def close(self) -> None:
233234
if self._writer_thread is not None:
234235
self._writer_thread.stop()
235236

237+
def _run_input_thread(self) -> None:
238+
"""
239+
Key thread target that wraps run_input_thread() to die gracefully if it raises
240+
an exception
241+
"""
242+
try:
243+
self.run_input_thread()
244+
except BaseException as error:
245+
self._app.call_later(
246+
self._app.panic,
247+
rich.traceback.Traceback(),
248+
)
249+
236250
def run_input_thread(self) -> None:
237251
"""Wait for input and dispatch events."""
238252
selector = selectors.DefaultSelector()
@@ -264,7 +278,5 @@ def more_data() -> bool:
264278
unicode_data = decode(read(fileno, 1024))
265279
for event in feed(unicode_data):
266280
self.process_event(event)
267-
except Exception as error:
268-
log(error)
269281
finally:
270282
selector.close()

0 commit comments

Comments
 (0)