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.
This commit is contained in:
Dax Raad 2026-03-20 10:33:53 -04:00
commit df44b41aaa
3 changed files with 35 additions and 12 deletions

View file

@ -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

View file

@ -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, {

View file

@ -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)
} }
} }