From 76f35ae1f153501f82f0676a1ebe93e06e18cdc2 Mon Sep 17 00:00:00 2001 From: Jokul Date: Wed, 8 Jul 2026 07:11:28 +0800 Subject: [PATCH] fix: KeyList TDZ crash and connection state desync - Move filteredKeys computed before useVirtualizer in KeyList.vue to fix ReferenceError (Cannot access 'filteredKeys' before initialization) that crashed the component setup and cascaded into '.t is not a function' render errors. - Wrap getInfo in try-catch in connection store connect() to clean up connectedIds/activeId when the client is lost between connect and getInfo, preventing a state where isConnected is true but no Redis client exists in the main process. --- src/components/KeyList.vue | 15 ++++++++------- src/stores/connection.ts | 11 ++++++++++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/components/KeyList.vue b/src/components/KeyList.vue index c449885..a2a4b60 100644 --- a/src/components/KeyList.vue +++ b/src/components/KeyList.vue @@ -27,6 +27,14 @@ const contextMenu = ref<{ visible: boolean; x: number; y: number; key: string }> // Shift+Click range selection const lastClickedIndex = ref(-1) +// Filtered keys (must be declared before useVirtualizer which references it) +const filteredKeys = computed(() => { + const keys = keyStore.keys.map(k => k.name) + return filterText.value + ? keys.filter(k => k.includes(filterText.value)) + : keys +}) + // Virtual scrolling const scrollRef = ref() const useVirtualization = computed(() => viewMode.value === 'list' && filteredKeys.value.length > 100) @@ -404,13 +412,6 @@ function toggleFolder(path: string) { } } -const filteredKeys = computed(() => { - const keys = keyStore.keys.map(k => k.name) - return filterText.value - ? keys.filter(k => k.includes(filterText.value)) - : keys -}) - const treeData = computed(() => { const separator = connStore.activeConnection?.separator || ':' const root: TreeNode[] = [] diff --git a/src/stores/connection.ts b/src/stores/connection.ts index 8aed18d..3644f56 100644 --- a/src/stores/connection.ts +++ b/src/stores/connection.ts @@ -131,7 +131,16 @@ export const useConnectionStore = defineStore('connection', () => { if (result.success) { connectedIds.value.push(conn.id) activeId.value = conn.id - serverInfoMap.value[conn.id] = await window.electronAPI.redis.getInfo(conn.id) + try { + serverInfoMap.value[conn.id] = await window.electronAPI.redis.getInfo(conn.id) + } catch { + // Client was lost between connect and getInfo — clean up to avoid + // leaving the renderer in a state where isConnected is true but no + // actual Redis client exists in the main process. + await disconnectById(conn.id) + error.value = 'Connection established but server info unavailable' + return + } // Restore last selected DB for this connection const lastDb = lastDbMap.value[conn.id] ?? 0 if (lastDb !== 0) {