diff options
| author | adamelmore <[email protected]> | 2026-01-27 06:27:27 -0600 |
|---|---|---|
| committer | adamelmore <[email protected]> | 2026-01-27 06:29:20 -0600 |
| commit | 095328faf439fbdc62506f3653875fbfec5c60ab (patch) | |
| tree | 707036011dcafaa2ad13d05eb52b041ea6f0d951 /packages/app/src/context | |
| parent | 743e83d9bfc050183be5bfb0f241ebe5faac6b35 (diff) | |
| download | opencode-095328faf439fbdc62506f3653875fbfec5c60ab.tar.gz opencode-095328faf439fbdc62506f3653875fbfec5c60ab.zip | |
fix(app): non-fatal error handling
Diffstat (limited to 'packages/app/src/context')
| -rw-r--r-- | packages/app/src/context/global-sync.tsx | 33 | ||||
| -rw-r--r-- | packages/app/src/context/notification.tsx | 6 | ||||
| -rw-r--r-- | packages/app/src/context/permission.tsx | 5 | ||||
| -rw-r--r-- | packages/app/src/context/server.tsx | 3 |
4 files changed, 32 insertions, 15 deletions
diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index 15a920584..c38ed8982 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -23,7 +23,7 @@ import { createStore, produce, reconcile, type SetStoreFunction, type Store } fr import { Binary } from "@opencode-ai/util/binary" import { retry } from "@opencode-ai/util/retry" import { useGlobalSDK } from "./global-sdk" -import { ErrorPage, type InitError } from "../pages/error" +import type { InitError } from "../pages/error" import { batch, createContext, @@ -823,11 +823,16 @@ function createGlobalSync() { .then((x) => x.data) .catch(() => undefined) if (!health?.healthy) { - setGlobalStore("error", new Error(language.t("error.globalSync.connectFailed", { url: globalSDK.url }))) + showToast({ + variant: "error", + title: language.t("dialog.server.add.error"), + description: language.t("error.globalSync.connectFailed", { url: globalSDK.url }), + }) + setGlobalStore("ready", true) return } - return Promise.all([ + const tasks = [ retry(() => globalSDK.client.path.get().then((x) => { setGlobalStore("path", x.data!) @@ -858,9 +863,22 @@ function createGlobalSync() { setGlobalStore("provider_auth", x.data ?? {}) }), ), - ]) - .then(() => setGlobalStore("ready", true)) - .catch((e) => setGlobalStore("error", e)) + ] + + const results = await Promise.allSettled(tasks) + const errors = results.filter((r): r is PromiseRejectedResult => r.status === "rejected").map((r) => r.reason) + + if (errors.length) { + const message = errors[0] instanceof Error ? errors[0].message : String(errors[0]) + const more = errors.length > 1 ? ` (+${errors.length - 1} more)` : "" + showToast({ + variant: "error", + title: language.t("common.requestFailed"), + description: message + more, + }) + } + + setGlobalStore("ready", true) } onMount(() => { @@ -926,9 +944,6 @@ export function GlobalSyncProvider(props: ParentProps) { const value = createGlobalSync() return ( <Switch> - <Match when={value.error}> - <ErrorPage error={value.error} /> - </Match> <Match when={value.ready}> <GlobalSyncContext.Provider value={value}>{props.children}</GlobalSyncContext.Provider> </Match> diff --git a/packages/app/src/context/notification.tsx b/packages/app/src/context/notification.tsx index 5e35f6ac0..6c110cae1 100644 --- a/packages/app/src/context/notification.tsx +++ b/packages/app/src/context/notification.tsx @@ -8,7 +8,8 @@ import { usePlatform } from "@/context/platform" import { useLanguage } from "@/context/language" import { useSettings } from "@/context/settings" import { Binary } from "@opencode-ai/util/binary" -import { base64Decode, base64Encode } from "@opencode-ai/util/encode" +import { base64Encode } from "@opencode-ai/util/encode" +import { decode64 } from "@/utils/base64" import { EventSessionError } from "@opencode-ai/sdk/v2" import { Persist, persisted } from "@/utils/persist" import { playSound, soundSrc } from "@/utils/sound" @@ -55,8 +56,7 @@ export const { use: useNotification, provider: NotificationProvider } = createSi const empty: Notification[] = [] const currentDirectory = createMemo(() => { - if (!params.dir) return - return base64Decode(params.dir) + return decode64(params.dir) }) const currentSession = createMemo(() => params.id) diff --git a/packages/app/src/context/permission.tsx b/packages/app/src/context/permission.tsx index 52878ba8f..d85f2ef24 100644 --- a/packages/app/src/context/permission.tsx +++ b/packages/app/src/context/permission.tsx @@ -6,7 +6,8 @@ import { Persist, persisted } from "@/utils/persist" import { useGlobalSDK } from "@/context/global-sdk" import { useGlobalSync } from "./global-sync" import { useParams } from "@solidjs/router" -import { base64Decode, base64Encode } from "@opencode-ai/util/encode" +import { base64Encode } from "@opencode-ai/util/encode" +import { decode64 } from "@/utils/base64" type PermissionRespondFn = (input: { sessionID: string @@ -53,7 +54,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple const globalSync = useGlobalSync() const permissionsEnabled = createMemo(() => { - const directory = params.dir ? base64Decode(params.dir) : undefined + const directory = decode64(params.dir) if (!directory) return false const [store] = globalSync.child(directory) return hasAutoAcceptPermissionConfig(store.config.permission) diff --git a/packages/app/src/context/server.tsx b/packages/app/src/context/server.tsx index 4a3f3c6d1..c307f6e72 100644 --- a/packages/app/src/context/server.tsx +++ b/packages/app/src/context/server.tsx @@ -95,10 +95,11 @@ export const { use: useServer, provider: ServerProvider } = createSimpleContext( const isReady = createMemo(() => ready() && !!state.active) const check = (url: string) => { + const signal = (AbortSignal as unknown as { timeout?: (ms: number) => AbortSignal }).timeout?.(3000) const sdk = createOpencodeClient({ baseUrl: url, fetch: platform.fetch, - signal: AbortSignal.timeout(3000), + signal, }) return sdk.global .health() |
