bugfix - tty + component
frdel committed
Aug 12, 2025 at 09:24 UTC
3db799fb2e965f3ce700249ca049a85c0043e448
2 files changed
+19
-3
python/helpers/tty_session.py
+18
-2
@@ -79,9 +79,25 @@ class TTYSession:
79
return await self._proc.wait()
80
81
def kill(self):
82
+ """Force-kill the running child process.
83
+
84
+ This is best-effort: if the process has already terminated (which can
85
+ happen if *close()* was called elsewhere or the child exited by
86
+ itself) we silently ignore the *ProcessLookupError* raised by
87
+ *asyncio.subprocess.Process.kill()*. This prevents race conditions
88
+ where multiple coroutines attempt to close the same session.
89
+ """
90
if self._proc is None:
83
- raise RuntimeError("TTYSpawn is not started")
84
- self._proc.kill()
91
+ # Already closed or never started – nothing to do
92
+ return
93
+
94
+ # Only attempt to kill if the process is still running
95
+ if getattr(self._proc, "returncode", None) is None:
96
+ try:
97
+ self._proc.kill()
98
+ except ProcessLookupError:
99
+ # Child already gone – treat as successfully killed
100
+ pass
101
102
async def read(self, timeout=None):
103
# Return any decoded text the child produced, or None on timeout
webui/js/components.js
+1
-1
@@ -165,7 +165,7 @@ export async function importComponent(path, targetElement) {
165
await Promise.all(loadPromises);
166
167
// Remove loading indicator
168
- const loadingEl = targetElement.querySelector(".loading");
168
+ const loadingEl = targetElement.querySelector(':scope > .loading');
169
if (loadingEl) {
170
targetElement.removeChild(loadingEl);
171
}