fix(opencode): catch completed MCP browser launcher failures (#51538)
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
This commit is contained in:
parent
a42f393c85
commit
b471c2b449
2 changed files with 41 additions and 2 deletions
|
|
@ -22,11 +22,14 @@ const layer = Layer.succeed(
|
|||
clearTimeout(timer)
|
||||
resume(Effect.fail(error))
|
||||
})
|
||||
subprocess.on("exit", (code) => {
|
||||
const onExit = (code: number | null) => {
|
||||
if (code === null || code === 0) return
|
||||
clearTimeout(timer)
|
||||
resume(Effect.fail(new Error(`Browser open failed with exit code ${code}`)))
|
||||
})
|
||||
}
|
||||
subprocess.on("exit", onExit)
|
||||
// On Windows and WSL, open() can return only after the launcher has exited.
|
||||
onExit(subprocess.exitCode)
|
||||
})
|
||||
}),
|
||||
}),
|
||||
|
|
|
|||
36
packages/opencode/test/mcp/browser.test.ts
Normal file
36
packages/opencode/test/mcp/browser.test.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { expect, mock, test } from "bun:test"
|
||||
import { spawn } from "node:child_process"
|
||||
import { once } from "node:events"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { Effect } from "effect"
|
||||
|
||||
await mock.module("@opencode-ai/core/open", () => ({
|
||||
openUrl: async (url: string) => {
|
||||
const code = new URL(url).pathname === "/successful" ? 0 : 23
|
||||
const subprocess = spawn(process.execPath, ["-e", `process.exit(${code})`], { stdio: "ignore" })
|
||||
await once(subprocess, "close")
|
||||
return subprocess
|
||||
},
|
||||
}))
|
||||
|
||||
const { McpBrowser } = await import("../../src/mcp/browser")
|
||||
|
||||
test("reports a browser launcher that exited before openUrl returned", async () => {
|
||||
const error = await Effect.runPromise(
|
||||
Effect.gen(function* () {
|
||||
const browser = yield* McpBrowser.Service
|
||||
return yield* Effect.flip(browser.open("https://example.com/authorize"))
|
||||
}).pipe(Effect.provide(LayerNode.compile(McpBrowser.node))),
|
||||
)
|
||||
|
||||
expect(error.message).toBe("Browser open failed with exit code 23")
|
||||
})
|
||||
|
||||
test("accepts a browser launcher that exited successfully before openUrl returned", async () => {
|
||||
await Effect.runPromise(
|
||||
Effect.gen(function* () {
|
||||
const browser = yield* McpBrowser.Service
|
||||
yield* browser.open("https://example.com/successful")
|
||||
}).pipe(Effect.provide(LayerNode.compile(McpBrowser.node))),
|
||||
)
|
||||
})
|
||||
Loading…
Reference in a new issue