summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context
diff options
context:
space:
mode:
authoradamelmore <[email protected]>2026-01-27 06:27:27 -0600
committeradamelmore <[email protected]>2026-01-27 06:29:20 -0600
commit095328faf439fbdc62506f3653875fbfec5c60ab (patch)
tree707036011dcafaa2ad13d05eb52b041ea6f0d951 /packages/app/src/context
parent743e83d9bfc050183be5bfb0f241ebe5faac6b35 (diff)
downloadopencode-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.tsx33
-rw-r--r--packages/app/src/context/notification.tsx6
-rw-r--r--packages/app/src/context/permission.tsx5
-rw-r--r--packages/app/src/context/server.tsx3
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()