-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
When my custom application code raises an exception in on_mount, Textual clears the screen (which hides the original error) and then crashes itself.
When debugging #247 I found that the way Textual crashes is rather unsatisfying way upon exit (Screenshot 1). Scrolling up reveals parts of the beautifully rendered error message, which unfortunately is cut off (Screenshot 2).
| Screenshot 1 | Screenshot 2 |
|---|---|
![]() |
![]() |
Based on my limited testing this affects both Windows and Linux, both on main and the css branch1.
Steps to reproduce
Repro: Insert raise RuntimeError in the get_markdown callback in examples/simple.py:
Lines 30 to 35 in cfefb36
| async def get_markdown(filename: str) -> None: | |
| with open(filename, "rt") as fh: | |
| readme = Markdown(fh.read(), hyperlinks=True) | |
| await body.update(readme) | |
| await self.call_later(get_markdown, "richreadme.md") |
Additional Information
The amount of info that is cut off depends on the terminal size, presumably because textual clears the current screen upon exit and everything above the fold stays.
terminal width 120x40
PS C:\Users\user\git\textual\examples> python .\simple.py ╭───────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────╮ │ │ │ C:\Python310\lib\site-packages\textual\message_pump.py:306 in on_callback │ │ │ │ 303 │ │ return await self.post_message(message) │ │ 304 │ │ │ 305 │ async def on_callback(self, event: events.Callback) -> None: │ │ ❱ 306 │ │ await event.callback() │ │ 307 │ │ │ 308 │ def emit_no_wait(self, message: Message) -> bool: │ │ 309 │ │ if self._parent: │ │ │ │ ╭───────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────╮ │Traceback (most recent call last):
File "C:\Python310\lib\site-packages\textual_timer.py", line 89, in _run
async def _run(self) -> None:
asyncio.exceptions.CancelledErrorDuring handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python310\lib\site-packages\textual\app.py", line 204, in run_app
await app.process_messages()
File "C:\Python310\lib\site-packages\textual\app.py", line 311, in process_messages
await self.animator.stop()
File "C:\Python310\lib\site-packages\textual_animator.py", line 119, in stop
await self._timer.stop()
File "C:\Python310\lib\site-packages\textual_timer.py", line 79, in stop
await self._task
asyncio.exceptions.CancelledErrorDuring handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\user\git\textual\examples\simple.py", line 38, in
MyApp.run(title="Simple App", log="textual.log")
File "C:\Python310\lib\site-packages\textual\app.py", line 206, in run
asyncio.run(run_app())
File "C:\Python310\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
return future.result()
asyncio.exceptions.CancelledError
terminal width 80x40
PS C:\Users\user\git\textual\examples> python .\simple.py ╭───────────────────── Traceback (most recent call last) ──────────────────────╮ │ │ │ C:\Python310\lib\site-packages\textual\message_pump.py:306 in on_callback │ │ │ │ 303 │ │ return await self.post_message(message) │ │ 304 │ │ │ 305 │ async def on_callback(self, event: events.Callback) -> None: │ │ ❱ 306 │ │ await event.callback() │ │ 307 │ │ │ 308 │ def emit_no_wait(self, message: Message) -> bool: │ │ 309 │ │ if self._parent: │ │ │ │ ╭───────────────────────────────── locals ─────────────────────────────────╮ │ │ │ event = Callback( │ │ │ │ │ callback=functools.partial(.get_markdown at 0x000001D291BED630>, │ │ │ │ 'richreadme.md') │ │Traceback (most recent call last):
File "C:\Python310\lib\site-packages\textual_timer.py", line 89, in _run
async def _run(self) -> None:
asyncio.exceptions.CancelledErrorDuring handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python310\lib\site-packages\textual\app.py", line 204, in run_app
await app.process_messages()
File "C:\Python310\lib\site-packages\textual\app.py", line 311, in process_messages
await self.animator.stop()
File "C:\Python310\lib\site-packages\textual_animator.py", line 119, in stop
await self._timer.stop()
File "C:\Python310\lib\site-packages\textual_timer.py", line 79, in stop
await self._task
asyncio.exceptions.CancelledErrorDuring handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\user\git\textual\examples\simple.py", line 38, in
MyApp.run(title="Simple App", log="textual.log")
File "C:\Python310\lib\site-packages\textual\app.py", line 206, in run
asyncio.run(run_app())
File "C:\Python310\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
return future.result()
asyncio.exceptions.CancelledError
terminal width 80x20
PS C:\Users\user\git\textual\examples> python .\simple.py ╭───────────────────── Traceback (most recent call last) ──────────────────────╮ │ │ │ C:\Python310\lib\site-packages\textual\message_pump.py:306 in on_callback │ │ │ │ 303 │ │ return await self.post_message(message) │ │ 304 │ │ │ 305 │ async def on_callback(self, event: events.Callback) -> None: │ │ ❱ 306 │ │ await event.callback() │ │ 307 │ │ │ 308 │ def emit_no_wait(self, message: Message) -> bool: │ │ 309 │ │ if self._parent: │ │ │ │ ╭───────────────────────────────── locals ─────────────────────────────────╮ │ │ │ event = Callback( │ │ │ │ │ callback=functools.partial(.get_markdown at 0x000001CA9AA1D630>, │ │ │ │ 'richreadme.md') │ │ │ │ ) │ │ │ │ self = MyApp(title='Simple App') │ │ │ ╰──────────────────────────────────────────────────────────────────────────╯ │ │ C:\Users\user\git\textual\examples\simple.py:32 in get_markdown │ │ │ │ 29 │ │ │ │ 30 │ │ async def get_markdown(filename: str) -> None: │ │ 31 │ │ │ with open(filename, "r") as fh: │ │ ❱ 32 │ │ │ │ readme = Markdown(fh.read(), hyperlinks=True) │ │ 33 │ │ │ await body.update(readme) │ │ 34 │ │ │ │ 35 │ │ await self.call_later(get_markdown, "richreadme.md") │ │ │ │ ╭───────────────────────────────── locals ─────────────────────────────────╮ │ │ │ body = ScrollView(name='ScrollView#1') │ │ │ │ fh = <_io.TextIOWrapper name='richreadme.md' mode='r' │ │ │ │ encoding='cp1252'> │ │ │ │ filename = 'richreadme.md' │ │ │ ╰──────────────────────────────────────────────────────────────────────────╯ │ │ │Traceback (most recent call last):
File "C:\Python310\lib\site-packages\textual_timer.py", line 89, in _run
async def _run(self) -> None:
asyncio.exceptions.CancelledErrorDuring handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python310\lib\site-packages\textual\app.py", line 204, in run_app
await app.process_messages()
File "C:\Python310\lib\site-packages\textual\app.py", line 311, in process_messages
await self.animator.stop()
File "C:\Python310\lib\site-packages\textual_animator.py", line 119, in stop
await self._timer.stop()
File "C:\Python310\lib\site-packages\textual_timer.py", line 79, in stop
await self._task
asyncio.exceptions.CancelledErrorDuring handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\user\git\textual\examples\simple.py", line 38, in
MyApp.run(title="Simple App", log="textual.log")
File "C:\Python310\lib\site-packages\textual\app.py", line 206, in run
asyncio.run(run_app())
File "C:\Python310\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
return future.result()
asyncio.exceptions.CancelledError
Footnotes
-
The simple example on the css branch only renders a black screen at the moment, but the crash behavior is the same. ↩

