From 340966195b613d068486f792b434d878a3e71fbd Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Thu, 13 Nov 2025 18:59:09 -0500 Subject: [PATCH] handle config errors gracefully --- .../opencode/src/cli/cmd/tui/context/exit.tsx | 7 ++- .../opencode/src/cli/cmd/tui/context/sync.tsx | 52 +++++++++++-------- packages/opencode/src/cli/cmd/tui/worker.ts | 1 + packages/opencode/src/project/instance.ts | 10 ++-- 4 files changed, 45 insertions(+), 25 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/context/exit.tsx b/packages/opencode/src/cli/cmd/tui/context/exit.tsx index 7d7feaa2..612c3915 100644 --- a/packages/opencode/src/cli/cmd/tui/context/exit.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/exit.tsx @@ -1,13 +1,18 @@ import { useRenderer } from "@opentui/solid" import { createSimpleContext } from "./helper" +import { FormatError } from "@/cli/error" export const { use: useExit, provider: ExitProvider } = createSimpleContext({ name: "Exit", init: (input: { onExit?: () => Promise }) => { const renderer = useRenderer() - return async () => { + return async (reason?: any) => { renderer.destroy() await input.onExit?.() + if (reason) { + const formatted = FormatError(reason) ?? JSON.stringify(reason) + process.stderr.write(formatted + "\n") + } process.exit(0) } }, diff --git a/packages/opencode/src/cli/cmd/tui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx index 6899cf57..eb8c3dfa 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sync.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sync.tsx @@ -17,6 +17,8 @@ import { useSDK } from "@tui/context/sdk" import { Binary } from "@/util/binary" import { createSimpleContext } from "./helper" import type { Snapshot } from "@/snapshot" +import { useExit } from "./exit" +import { onMount } from "solid-js" export const { use: useSync, provider: SyncProvider } = createSimpleContext({ name: "Sync", @@ -215,28 +217,36 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ } }) - // blocking - Promise.all([ - sdk.client.config.providers({ throwOnError: true }).then((x) => setStore("provider", x.data!.providers)), - sdk.client.app.agents({ throwOnError: true }).then((x) => setStore("agent", x.data ?? [])), - sdk.client.config.get({ throwOnError: true }).then((x) => setStore("config", x.data!)), - ]).then(() => { - setStore("status", "partial") - // non-blocking + const exit = useExit() + + onMount(() => { + // blocking Promise.all([ - sdk.client.session.list().then((x) => - setStore( - "session", - (x.data ?? []).toSorted((a, b) => a.id.localeCompare(b.id)), - ), - ), - sdk.client.command.list().then((x) => setStore("command", x.data ?? [])), - sdk.client.lsp.status().then((x) => setStore("lsp", x.data!)), - sdk.client.mcp.status().then((x) => setStore("mcp", x.data!)), - sdk.client.formatter.status().then((x) => setStore("formatter", x.data!)), - ]).then(() => { - setStore("status", "complete") - }) + sdk.client.config.providers({ throwOnError: true }).then((x) => setStore("provider", x.data!.providers)), + sdk.client.app.agents({ throwOnError: true }).then((x) => setStore("agent", x.data ?? [])), + sdk.client.config.get({ throwOnError: true }).then((x) => setStore("config", x.data!)), + ]) + .then(() => { + setStore("status", "partial") + // non-blocking + Promise.all([ + sdk.client.session.list().then((x) => + setStore( + "session", + (x.data ?? []).toSorted((a, b) => a.id.localeCompare(b.id)), + ), + ), + sdk.client.command.list().then((x) => setStore("command", x.data ?? [])), + sdk.client.lsp.status().then((x) => setStore("lsp", x.data!)), + sdk.client.mcp.status().then((x) => setStore("mcp", x.data!)), + sdk.client.formatter.status().then((x) => setStore("formatter", x.data!)), + ]).then(() => { + setStore("status", "complete") + }) + }) + .catch(async (e) => { + await exit(e) + }) }) const result = { diff --git a/packages/opencode/src/cli/cmd/tui/worker.ts b/packages/opencode/src/cli/cmd/tui/worker.ts index 32cd5562..db1eb8ec 100644 --- a/packages/opencode/src/cli/cmd/tui/worker.ts +++ b/packages/opencode/src/cli/cmd/tui/worker.ts @@ -43,6 +43,7 @@ export const rpc = { } }, async shutdown() { + Log.Default.info("worker shutting down") await Instance.disposeAll() await server.stop(true) }, diff --git a/packages/opencode/src/project/instance.ts b/packages/opencode/src/project/instance.ts index 39625e08..6e8ebb7a 100644 --- a/packages/opencode/src/project/instance.ts +++ b/packages/opencode/src/project/instance.ts @@ -53,10 +53,14 @@ export const Instance = { await State.dispose(Instance.directory) }, async disposeAll() { + Log.Default.info("disposing all instances") for (const [_key, value] of cache) { - await context.provide(await value, async () => { - await Instance.dispose() - }) + const awaited = await value.catch(() => {}) + if (awaited) { + await context.provide(await value, async () => { + await Instance.dispose() + }) + } } cache.clear() },