Fix retry crash for unregistered remotes in the Sessions popup

Opening a window whose target was removed from the registry (its tab
stays open by design) and failing landed in the action menu with a
"重试连接" row that indexed self.entries directly and raised KeyError,
killing the popup with a traceback.

Only offer the retry action for registered targets, degrade a stale
retry row to a message, and keep the popup alive when a handler raises
anything unexpected instead of dying with a traceback.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 02:58:45 +00:00
co-authored by Claude Fable 5.1
parent 6f933e1c80
commit 6b906de476
2 changed files with 70 additions and 7 deletions
+25 -7
View File
@@ -616,7 +616,13 @@ class SessionSelector:
except curses.error:
continue
outcome = self._handle_key(key, filtered)
try:
outcome = self._handle_key(key, filtered)
except Exception as error: # noqa: BLE001 - keep the popup alive
# A handler bug must not replace the popup with a traceback.
self._show_main()
self.message = f"内部错误:{type(error).__name__}: {error}"
continue
if isinstance(outcome, SelectorResult) or outcome is False:
return outcome if isinstance(outcome, SelectorResult) else None
@@ -797,7 +803,12 @@ class SessionSelector:
elif source.kind == "retry":
rows.append(_action_row(source, "retry", "action-retry", "重试连接"))
if source.kind != "retry" and source.error is not None and source.target is not None:
if (
source.kind != "retry"
and source.error is not None
and source.target is not None
and source.target in self.entries
):
rows.append(_action_row(source, "retry", "action-retry", "重试连接"))
if source.kind == "window" and source.endpoint_key is not None:
@@ -1008,8 +1019,15 @@ class SessionSelector:
self._show_actions(row)
elif row.kind in {"retry", "action-retry"}:
assert row.target is not None
entry = self.entries.get(row.target)
if entry is None:
# The window's target was removed from the registry while its
# tab stayed open; there is nothing to re-query.
self._show_main()
self.message = f"{row.target} 未登记为远端,无法重试;可通过“添加远端”重新登记"
return None
self.results.pop(row.target, None)
self.pool.enqueue(self.entries[row.target])
self.pool.enqueue(entry)
self._show_main()
self.message = f"正在重试 {row.target}"
elif row.kind == "action-new":
@@ -1122,7 +1140,7 @@ class SessionSelector:
return result
try:
self.activate_handler(result)
except (OSError, RuntimeError, ValueError) as error:
except Exception as error: # noqa: BLE001 - shown inside the popup
detail = str(error).strip() or "未知错误"
self.message = f"打开失败:{detail}"
if row is not None:
@@ -1144,7 +1162,7 @@ class SessionSelector:
if self.rename_handler is not None:
try:
self.rename_handler(self.input_key, normalized)
except (OSError, RuntimeError, ValueError) as error:
except Exception as error: # noqa: BLE001 - shown inside the popup
self.message = str(error)
return None
@@ -1280,7 +1298,7 @@ class SessionSelector:
self.pending_action = None
try:
outcome = future.result()
except (OSError, RuntimeError, ValueError) as error:
except Exception as error: # noqa: BLE001 - shown inside the popup
self._show_main()
entry = self.entries.get(action.target)
if entry is not None:
@@ -1368,7 +1386,7 @@ class SessionSelector:
)
try:
self.windows = list(self.close_window_handler(window_id))
except (OSError, RuntimeError, ValueError) as error:
except Exception as error: # noqa: BLE001 - shown inside the popup
self.message = f"关闭 Tab 失败:{error}"
return
self._show_main()