Repository navigation
4.8.2 TUI (text.py) raw traceback text prints straight onto the terminal grid #11026
Description
Activity
It failed to have any effect, of course. It's as if the highest-level-set LLMs are turning dumb now so we're forced to learn how not to do everything wrong in a world without them...
I called GPE out on its BS, and prompted something that would actually work - WITHOUT creating a log file that it insists on creating every time:
The traceback bypassed your touchwin() fix because it is an unhandled asyncio background task exception writing directly to standard error, not a standard application event.
When get_estimatefee timed out with a RequestTimedOut exception, the background task crashed silently. Because the task failed, it never triggered your wallet's event listener to set need_update = True. Since your UI's refresh() method was never actually invoked, touchwin() never had the opportunity to execute and paint over the text. Meanwhile, asyncio's default exception handler caught the "Task exception was never retrieved" error and dumped the traceback straight to sys.stderr, physically writing over the curses display buffer.
...
To discard the tracebacks entirely without creating any log files on your drive, you can redirect standard error to the operating system's null device (os.devnull). This acts as a black hole, instantly deleting the asyncio exception text before it can reach the curses display buffer.
def main(self): import os sys.stderr = open(os.devnull, 'w') self.daemon.start_network() tty.setraw(sys.stdin) try:So I'm trying that now (after pulling out .touchwin) & will update here when that successfully fails to have any effect too.
P.S. Any sort of error other than one that would prevent me being alerted to a new output to any of my wallet addresses, I simply don't care about - I'm not using TUI as a spending wallet or wondering what my balance is in fiat. Someone else will have to work on fixing these external non-UTXO update errors if they're worth caring about in general.
And of course that failed as well. After yet another callout of GPE's BS, it replied:
sys.stderr = open(os.devnull, 'w') failed because Electrum's logging system and asyncio capture the low-level operating system file descriptor (fd 2 / sys.stderr) during startup before main() ever runs. Modifying the high-level sys.stderr variable later does not affect stream handlers already bound to the terminal's OS file descriptor.
To discard all traceback output at the OS kernel level without creating any files on disk, redirect file descriptor 2 directly to /dev/null at the very top
(It took a few more prompts to obtain a relatively-neat edit of the imports, with
import osput in that order, vs scrambling the original order like names in a hat)import tty import sys import os import curses import datetime import locale from decimal import Decimal import getpass from typing import TYPE_CHECKING, Optional # Silently discard low-level OS stderr (fd 2) and sys.stderr to prevent asyncio tracebacks from corrupting curses try: _devnull = os.open(os.devnull, os.O_WRONLY) os.dup2(_devnull, 2) os.close(_devnull) sys.stderr = open(os.devnull, 'w') sys.__stderr__ = sys.stderr except Exception: pass(rest of file left as-is)
Why this works
os.dup2(_devnull, 2) replaces standard error at the operating system layer. Any write targeted at file descriptor 2—whether from Python's C core, sys.stderr, asyncio, or background logging handlers—is immediately discarded by the kernel before hitting the terminal grid. No log files or disk writes are created.
Here I go with the latest relaunch of likely BS, after reverting out of
def main(self):import os sys.stderr = open(os.devnull, 'w')The
Silently discard low-level OS stderr (fd 2) and sys.stderr to prevent asyncio tracebacks from corrupting curses
block with
import osabove may have actually worked. Both mainnet & testnet wallets have been sitting pretty in TUI since my last comment time. Computer is prevented from sleeping or spinning down hard drives (so I can run WeeWX without downtime, and not as a daemon, I want to read its temperature prints directly).I even made a testnet faucet request to make sure that logic didn't kill my TUI alert PR #11019 (cough #11016 cough), and that still works:

Hmm, I discovered both of the wallet instances returned to command line suspiciously around 24 hours from launch, but can't say for sure without timestamps on each line. macOS doesn't appear to be resetting WeeWX every 24 hours, so IDK why the Electrum TUI wallet instances effectively CTRL-C'd themselves.
Description
For me in particular, it's the
blockchain.estimatefeetimeout exception traceback (which I've seen, along withexchange_rate, even when I run v4.5.8 GUI from Python through Tor), though I suppose it could be anything for anyone (unless I'm the only person on earth who runs 4.8.2 as TUI). The traceback is cleared the instant I spin my scroll wheel, returning to the normal/fully-functional TUI grid.On prompting to give me the absolute minimum fix necessary, Gemini Pro Extended suggested I turn this
gui/text.pyblock:into this (added line in caps for highlighting only, but lowercase in actual file):
This (in conjunction with .refresh) is to force curses to repaint the entire grid whenever a background update fires?
So I saved & relaunched, and will update this issue if that fix doesn't work. I have mainnet & testnet 4.8.2 TUI instances running side-by-side, so more opportunity to see the traceback return sooner.
P.S. I asked Gemini why it settled on
self.stdscr.touchwin()vsself.stdscr.clearok(True)...the latter
& the former
So for seizure prevention, the former was the better choice.