summaryrefslogtreecommitdiffhomepage
path: root/packages/desktop/src
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-22 19:16:50 -0600
committerAdam <[email protected]>2025-12-22 19:16:54 -0600
commit680a63e3dee5bf2748eaf844b4e9b838d2859f16 (patch)
tree9b6c4de0b0f2c664a1075c58e5f1c39b125f4590 /packages/desktop/src
parent3a54ab68d1f9684d86434dd6e890d43c63adf461 (diff)
downloadopencode-680a63e3dee5bf2748eaf844b4e9b838d2859f16.tar.gz
opencode-680a63e3dee5bf2748eaf844b4e9b838d2859f16.zip
fix(desktop): better error messages on connection failure
Diffstat (limited to 'packages/desktop/src')
-rw-r--r--packages/desktop/src/app.tsx6
-rw-r--r--packages/desktop/src/context/global-sync.tsx9
-rw-r--r--packages/desktop/src/pages/error.tsx40
3 files changed, 43 insertions, 12 deletions
diff --git a/packages/desktop/src/app.tsx b/packages/desktop/src/app.tsx
index 9d000b8ff..11216643e 100644
--- a/packages/desktop/src/app.tsx
+++ b/packages/desktop/src/app.tsx
@@ -35,10 +35,10 @@ const url = iife(() => {
if (location.hostname.includes("opencode.ai")) return "http://localhost:4096"
if (window.__OPENCODE__) return `http://127.0.0.1:${window.__OPENCODE__.port}`
- if (import.meta.env.VITE_OPENCODE_SERVER)
- return `http://${import.meta.env.VITE_OPENCODE_SERVER_HOST}:${import.meta.env.VITE_OPENCODE_SERVER_PORT ?? "4096"}`
+ if (import.meta.env.DEV)
+ return `http://${import.meta.env.VITE_OPENCODE_SERVER_HOST ?? "localhost"}:${import.meta.env.VITE_OPENCODE_SERVER_PORT ?? "4096"}`
- return "/"
+ return "http://localhost:4096"
})
export function App() {
diff --git a/packages/desktop/src/context/global-sync.tsx b/packages/desktop/src/context/global-sync.tsx
index 27a89e7bc..ae40555d6 100644
--- a/packages/desktop/src/context/global-sync.tsx
+++ b/packages/desktop/src/context/global-sync.tsx
@@ -295,6 +295,15 @@ function createGlobalSync() {
})
async function bootstrap() {
+ const health = await globalSDK.client.global.health().then((x) => x.data)
+ if (!health?.healthy) {
+ setGlobalStore(
+ "error",
+ new Error(`Could not connect to server. Is there a server running at \`${globalSDK.url}\`?`),
+ )
+ return
+ }
+
return Promise.all([
retry(() =>
globalSDK.client.path.get().then((x) => {
diff --git a/packages/desktop/src/pages/error.tsx b/packages/desktop/src/pages/error.tsx
index c7330c298..9914279ad 100644
--- a/packages/desktop/src/pages/error.tsx
+++ b/packages/desktop/src/pages/error.tsx
@@ -62,27 +62,49 @@ function formatInitError(error: InitError): string {
}
}
-function formatErrorChain(error: unknown, depth = 0): string {
+function formatErrorChain(error: unknown, depth = 0, parentMessage?: string): string {
if (!error) return "Unknown error"
- const indent = depth > 0 ? `\n${"─".repeat(40)}\nCaused by:\n` : ""
-
if (isInitError(error)) {
- return indent + formatInitError(error)
+ const message = formatInitError(error)
+ if (depth > 0 && parentMessage === message) return ""
+ const indent = depth > 0 ? `\n${"─".repeat(40)}\nCaused by:\n` : ""
+ return indent + message
}
if (error instanceof Error) {
- const parts = [indent + `${error.name}: ${error.message}`]
- if (error.stack) {
- parts.push(error.stack)
+ const isDuplicate = depth > 0 && parentMessage === error.message
+ const parts: string[] = []
+ const indent = depth > 0 ? `\n${"─".repeat(40)}\nCaused by:\n` : ""
+
+ if (!isDuplicate) {
+ // Stack already includes error name and message, so prefer it
+ parts.push(indent + (error.stack ?? `${error.name}: ${error.message}`))
+ } else if (error.stack) {
+ // Duplicate message - only show the stack trace lines (skip message)
+ const trace = error.stack.split("\n").slice(1).join("\n").trim()
+ if (trace) {
+ parts.push(trace)
+ }
}
+
if (error.cause) {
- parts.push(formatErrorChain(error.cause, depth + 1))
+ const causeResult = formatErrorChain(error.cause, depth + 1, error.message)
+ if (causeResult) {
+ parts.push(causeResult)
+ }
}
+
return parts.join("\n\n")
}
- if (typeof error === "string") return indent + error
+ if (typeof error === "string") {
+ if (depth > 0 && parentMessage === error) return ""
+ const indent = depth > 0 ? `\n${"─".repeat(40)}\nCaused by:\n` : ""
+ return indent + error
+ }
+
+ const indent = depth > 0 ? `\n${"─".repeat(40)}\nCaused by:\n` : ""
return indent + JSON.stringify(error, null, 2)
}