|
12 | 12 | from typing import TYPE_CHECKING, Any |
13 | 13 |
|
14 | 14 | import rich.repr |
| 15 | +import rich.traceback |
15 | 16 |
|
16 | 17 | from .. import events, log |
17 | 18 | from .._xterm_parser import XTermParser |
@@ -164,7 +165,7 @@ def on_terminal_resize(signum, stack) -> None: |
164 | 165 | self.write("\x1b[?25l") # Hide cursor |
165 | 166 | self.write("\033[?1003h\n") |
166 | 167 | self.flush() |
167 | | - self._key_thread = Thread(target=self.run_input_thread) |
| 168 | + self._key_thread = Thread(target=self._run_input_thread) |
168 | 169 | send_size_event() |
169 | 170 | self._key_thread.start() |
170 | 171 | self._request_terminal_sync_mode_support() |
@@ -233,6 +234,19 @@ def close(self) -> None: |
233 | 234 | if self._writer_thread is not None: |
234 | 235 | self._writer_thread.stop() |
235 | 236 |
|
| 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 | + |
236 | 250 | def run_input_thread(self) -> None: |
237 | 251 | """Wait for input and dispatch events.""" |
238 | 252 | selector = selectors.DefaultSelector() |
@@ -264,7 +278,5 @@ def more_data() -> bool: |
264 | 278 | unicode_data = decode(read(fileno, 1024)) |
265 | 279 | for event in feed(unicode_data): |
266 | 280 | self.process_event(event) |
267 | | - except Exception as error: |
268 | | - log(error) |
269 | 281 | finally: |
270 | 282 | selector.close() |
0 commit comments