diff --git a/apps/desktop/src/stores/connectionStore.ts b/apps/desktop/src/stores/connectionStore.ts index e57b09c35c..4a62ae9aa8 100644 --- a/apps/desktop/src/stores/connectionStore.ts +++ b/apps/desktop/src/stores/connectionStore.ts @@ -1238,6 +1238,22 @@ export const useConnectionStore = defineStore("connection", () => { recordConnectionError(connectionId, error); } + async function runConnectionTreeMetadataLoad(connectionId: string, node: TreeNode | null | undefined, work: (load: TreeNodeLoadHandle) => Promise): Promise { + if (!node) return; + + let load = beginTreeNodeLoad(node); + try { + await ensureConnected(connectionId); + load = reclaimTreeNodeLoad(load, node); + return await work(load); + } catch (error) { + recordMetadataLoadError(connectionId, error, load); + throw error; + } finally { + finishTreeNodeLoad(load); + } + } + async function withConnectionAttemptTimeout(promise: Promise, config: ConnectionConfig): Promise { const timeoutMs = connectionAttemptTimeoutMs(config, tunnelProfileStore.profileById); const timeoutMessage = connectionAttemptTimeoutMessage(timeoutMs); @@ -4557,12 +4573,7 @@ export const useConnectionStore = defineStore("connection", () => { async function loadRedisDatabases(connectionId: string) { const node = findConnectionNode(connectionId); - if (!node) return; - - let load = beginTreeNodeLoad(node); - try { - await ensureConnected(connectionId); - load = reclaimTreeNodeLoad(load, node); + return runConnectionTreeMetadataLoad(connectionId, node, async (load) => { const dbs = await withMetadataLoadTimeout(connectionId, api.redisListDatabases(connectionId), "Redis databases"); const config = getConfig(connectionId); const visibleNames = filterVisibleDatabaseNames( @@ -4597,22 +4608,12 @@ export const useConnectionStore = defineStore("connection", () => { ), ); targetNode.isExpanded = true; - } catch (e) { - recordMetadataLoadError(connectionId, e, load); - throw e; - } finally { - finishTreeNodeLoad(load); - } + }); } async function loadEtcdRoot(connectionId: string) { const node = findConnectionNode(connectionId); - if (!node) return; - - let load = beginTreeNodeLoad(node); - try { - await ensureConnected(connectionId); - load = reclaimTreeNodeLoad(load, node); + return runConnectionTreeMetadataLoad(connectionId, node, async (load) => { const targetNode = treeNodeLoadTarget(load); if (!targetNode) return; const etcdAccess = await ensureEtcdAccessCapabilities(connectionId, { force: true, verifyHealth: false }); @@ -4651,22 +4652,12 @@ export const useConnectionStore = defineStore("connection", () => { } setChildren(targetNode, withSavedSqlRoot(connectionId, children, targetNode)); targetNode.isExpanded = true; - } catch (e) { - recordMetadataLoadError(connectionId, e, load); - throw e; - } finally { - finishTreeNodeLoad(load); - } + }); } async function loadZooKeeperRoot(connectionId: string) { const node = findConnectionNode(connectionId); - if (!node) return; - - let load = beginTreeNodeLoad(node); - try { - await ensureConnected(connectionId); - load = reclaimTreeNodeLoad(load, node); + return runConnectionTreeMetadataLoad(connectionId, node, async (load) => { const targetNode = treeNodeLoadTarget(load); if (!targetNode) return; setChildren( @@ -4688,22 +4679,12 @@ export const useConnectionStore = defineStore("connection", () => { ), ); targetNode.isExpanded = true; - } catch (e) { - recordMetadataLoadError(connectionId, e, load); - throw e; - } finally { - finishTreeNodeLoad(load); - } + }); } async function loadConsulRoot(connectionId: string) { const node = findConnectionNode(connectionId); - if (!node) return; - - let load = beginTreeNodeLoad(node); - try { - await ensureConnected(connectionId); - load = reclaimTreeNodeLoad(load, node); + return runConnectionTreeMetadataLoad(connectionId, node, async (load) => { const targetNode = treeNodeLoadTarget(load); if (!targetNode) return; setChildren( @@ -4734,12 +4715,7 @@ export const useConnectionStore = defineStore("connection", () => { ), ); targetNode.isExpanded = true; - } catch (e) { - recordMetadataLoadError(connectionId, e, load); - throw e; - } finally { - finishTreeNodeLoad(load); - } + }); } async function loadMqttTopics(connectionId: string) { @@ -5083,12 +5059,7 @@ export const useConnectionStore = defineStore("connection", () => { async function loadMilvusDatabases(connectionId: string) { const node = findConnectionNode(connectionId); - if (!node) return; - - let load = beginTreeNodeLoad(node); - try { - await ensureConnected(connectionId); - load = reclaimTreeNodeLoad(load, node); + return runConnectionTreeMetadataLoad(connectionId, node, async (load) => { const dbs = await withMetadataLoadTimeout(connectionId, api.documentListDatabases(connectionId), "Milvus databases"); const targetNode = treeNodeLoadTarget(load); if (!targetNode) return; @@ -5109,12 +5080,7 @@ export const useConnectionStore = defineStore("connection", () => { ), ); targetNode.isExpanded = true; - } catch (e) { - recordMetadataLoadError(connectionId, e, load); - throw e; - } finally { - finishTreeNodeLoad(load); - } + }); } async function loadVectorCollections(connectionId: string, database?: string) { @@ -5123,12 +5089,7 @@ export const useConnectionStore = defineStore("connection", () => { const effectiveDb = database || config?.database || (config?.db_type === "chromadb" ? "default_database" : "default"); // Milvus groups collections under a per-database node; other vector stores stay flat under the connection. const node = isMilvus && database ? findNode(treeNodes.value, `${connectionId}:${database}`) : findConnectionNode(connectionId); - if (!node) return; - - let load = beginTreeNodeLoad(node); - try { - await ensureConnected(connectionId); - load = reclaimTreeNodeLoad(load, node); + return runConnectionTreeMetadataLoad(connectionId, node, async (load) => { const collections = await withMetadataLoadTimeout(connectionId, api.vectorListCollections(connectionId, effectiveDb), "vector collections"); const sorted = [...collections].sort((a, b) => a.name.localeCompare(b.name)); const collectionChildren = sorted.map((info) => ({ @@ -5145,12 +5106,7 @@ export const useConnectionStore = defineStore("connection", () => { if (!targetNode) return; setChildren(targetNode, isMilvus && database ? collectionChildren : withSavedSqlRoot(connectionId, collectionChildren, targetNode)); targetNode.isExpanded = true; - } catch (e) { - recordMetadataLoadError(connectionId, e, load); - throw e; - } finally { - finishTreeNodeLoad(load); - } + }); } async function loadMongoCollections(connectionId: string, database: string) {