Browse Source

fix: handle undefined from Npm.which in all callers

Npm.which now returns undefined instead of throwing when binary not found.
Update all callers to check for undefined and return early.
Avoid explicit union types by using a resolved variable pattern.
Dax Raad 1 month ago
parent
commit
df44b41aaa

+ 6 - 2
packages/opencode/src/format/formatter.ts

@@ -92,7 +92,9 @@ export const oxfmt: Info = {
         devDependencies?: Record<string, string>
         devDependencies?: Record<string, string>
       }>(item)
       }>(item)
       if (json.dependencies?.oxfmt || json.devDependencies?.oxfmt) {
       if (json.dependencies?.oxfmt || json.devDependencies?.oxfmt) {
-        return [await Npm.which("oxfmt"), "$FILE"]
+        const bin = await Npm.which("oxfmt")
+        if (!bin) return false
+        return [bin, "$FILE"]
       }
       }
     }
     }
     return false
     return false
@@ -134,7 +136,9 @@ export const biome: Info = {
     for (const config of configs) {
     for (const config of configs) {
       const found = await Filesystem.findUp(config, Instance.directory, Instance.worktree)
       const found = await Filesystem.findUp(config, Instance.directory, Instance.worktree)
       if (found.length > 0) {
       if (found.length > 0) {
-        return [await Npm.which("@biomejs/biome"), "check", "--write", "$FILE"]
+        const bin = await Npm.which("@biomejs/biome")
+        if (!bin) return false
+        return [bin, "check", "--write", "$FILE"]
       }
       }
     }
     }
     return false
     return false

+ 28 - 9
packages/opencode/src/lsp/server.ts

@@ -103,7 +103,9 @@ export namespace LSPServer {
       const tsserver = Module.resolve("typescript/lib/tsserver.js", Instance.directory)
       const tsserver = Module.resolve("typescript/lib/tsserver.js", Instance.directory)
       log.info("typescript server", { tsserver })
       log.info("typescript server", { tsserver })
       if (!tsserver) return
       if (!tsserver) return
-      const proc = spawn(await Npm.which("typescript-language-server"), ["--stdio"], {
+      const bin = await Npm.which("typescript-language-server")
+      if (!bin) return
+      const proc = spawn(bin, ["--stdio"], {
         cwd: root,
         cwd: root,
         env: {
         env: {
           ...process.env,
           ...process.env,
@@ -129,7 +131,9 @@ export namespace LSPServer {
       const args: string[] = []
       const args: string[] = []
       if (!binary) {
       if (!binary) {
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
-        binary = await Npm.which("@vue/language-server")
+        const resolved = await Npm.which("@vue/language-server")
+        if (!resolved) return
+        binary = resolved
       }
       }
       args.push("--stdio")
       args.push("--stdio")
       const proc = spawn(binary, args, {
       const proc = spawn(binary, args, {
@@ -322,6 +326,7 @@ export namespace LSPServer {
         const resolved = Module.resolve("biome", root)
         const resolved = Module.resolve("biome", root)
         if (!resolved) return
         if (!resolved) return
         bin = await Npm.which("biome")
         bin = await Npm.which("biome")
+        if (!bin) return
         args = ["lsp-proxy", "--stdio"]
         args = ["lsp-proxy", "--stdio"]
       }
       }
 
 
@@ -488,7 +493,9 @@ export namespace LSPServer {
       const args = []
       const args = []
       if (!binary) {
       if (!binary) {
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
-        binary = await Npm.which("pyright")
+        const resolved = await Npm.which("pyright")
+        if (!resolved) return
+        binary = resolved
       }
       }
       args.push("--stdio")
       args.push("--stdio")
 
 
@@ -1003,7 +1010,9 @@ export namespace LSPServer {
       const args: string[] = []
       const args: string[] = []
       if (!binary) {
       if (!binary) {
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
-        binary = await Npm.which("svelte-language-server")
+        const resolved = await Npm.which("svelte-language-server")
+        if (!resolved) return
+        binary = resolved
       }
       }
       args.push("--stdio")
       args.push("--stdio")
       const proc = spawn(binary, args, {
       const proc = spawn(binary, args, {
@@ -1035,7 +1044,9 @@ export namespace LSPServer {
       const args: string[] = []
       const args: string[] = []
       if (!binary) {
       if (!binary) {
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
-        binary = await Npm.which("@astrojs/language-server")
+        const resolved = await Npm.which("@astrojs/language-server")
+        if (!resolved) return
+        binary = resolved
       }
       }
       args.push("--stdio")
       args.push("--stdio")
       const proc = spawn(binary, args, {
       const proc = spawn(binary, args, {
@@ -1284,7 +1295,9 @@ export namespace LSPServer {
       const args: string[] = []
       const args: string[] = []
       if (!binary) {
       if (!binary) {
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
-        binary = await Npm.which("yaml-language-server")
+        const resolved = await Npm.which("yaml-language-server")
+        if (!resolved) return
+        binary = resolved
       }
       }
       args.push("--stdio")
       args.push("--stdio")
       const proc = spawn(binary, args, {
       const proc = spawn(binary, args, {
@@ -1449,7 +1462,9 @@ export namespace LSPServer {
       const args: string[] = []
       const args: string[] = []
       if (!binary) {
       if (!binary) {
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
-        binary = await Npm.which("intelephense")
+        const resolved = await Npm.which("intelephense")
+        if (!resolved) return
+        binary = resolved
       }
       }
       args.push("--stdio")
       args.push("--stdio")
       const proc = spawn(binary, args, {
       const proc = spawn(binary, args, {
@@ -1531,7 +1546,9 @@ export namespace LSPServer {
       const args: string[] = []
       const args: string[] = []
       if (!binary) {
       if (!binary) {
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
-        binary = await Npm.which("bash-language-server")
+        const resolved = await Npm.which("bash-language-server")
+        if (!resolved) return
+        binary = resolved
       }
       }
       args.push("start")
       args.push("start")
       const proc = spawn(binary, args, {
       const proc = spawn(binary, args, {
@@ -1724,7 +1741,9 @@ export namespace LSPServer {
       const args: string[] = []
       const args: string[] = []
       if (!binary) {
       if (!binary) {
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
         if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
-        binary = await Npm.which("dockerfile-language-server-nodejs")
+        const resolved = await Npm.which("dockerfile-language-server-nodejs")
+        if (!resolved) return
+        binary = resolved
       }
       }
       args.push("--stdio")
       args.push("--stdio")
       const proc = spawn(binary, args, {
       const proc = spawn(binary, args, {

+ 1 - 1
packages/opencode/src/npm/index.ts

@@ -175,7 +175,7 @@ export namespace Npm {
     await rm(path.join(dir, "package-lock.json"), { force: true })
     await rm(path.join(dir, "package-lock.json"), { force: true })
     await add(pkg)
     await add(pkg)
     const resolved = await pick()
     const resolved = await pick()
-    if (!resolved) throw new Error(`No binary found for package "${pkg}" after install`)
+    if (!resolved) return
     return path.join(binDir, resolved)
     return path.join(binDir, resolved)
   }
   }
 }
 }