fix(httpapi): return session busy error bodies (#28684)

This commit is contained in:
Shoubhit Dash
2026-05-21 22:53:49 +05:30
committed by GitHub
parent 6c24062d2f
commit 82b796ce31
4 changed files with 48 additions and 8 deletions
@@ -142,4 +142,19 @@ describe("PublicApi OpenAPI v2 errors", () => {
)
}
})
test("documents session busy errors", () => {
const spec = OpenApi.fromApi(PublicApi) as OpenApiSpec
for (const route of [
["post", "/session/{sessionID}/shell"],
["post", "/session/{sessionID}/revert"],
["post", "/session/{sessionID}/unrevert"],
["delete", "/session/{sessionID}/message/{messageID}"],
] as const) {
expect(componentName(responseRef(spec.paths[route[1]]?.[route[0]]?.responses?.["409"]) ?? "")).toBe(
"SessionBusyError",
)
}
})
})
@@ -1,7 +1,7 @@
import { afterEach, describe, expect } from "bun:test"
import { mkdir } from "node:fs/promises"
import path from "node:path"
import { Effect, Layer } from "effect"
import { Cause, Effect, Exit, Layer } from "effect"
import { Flag } from "@opencode-ai/core/flag/flag"
import { registerAdapter } from "../../src/control-plane/adapters"
import type { WorkspaceAdapter } from "../../src/control-plane/types"
@@ -13,6 +13,7 @@ import { InstanceBootstrap as InstanceBootstrapService } from "../../src/project
import { InstanceStore } from "../../src/project/instance-store"
import { Project } from "../../src/project/project"
import { Server } from "../../src/server/server"
import * as HttpSessionError from "../../src/server/routes/instance/httpapi/handlers/session-errors"
import { SessionPaths } from "../../src/server/routes/instance/httpapi/groups/session"
import { Session } from "@/session/session"
import { MessageID, PartID, SessionID, type SessionID as SessionIDType } from "../../src/session/schema"
@@ -215,6 +216,22 @@ afterEach(async () => {
})
describe("session HttpApi", () => {
it.effect("maps busy sessions to public session busy errors", () =>
Effect.gen(function* () {
const sessionID = SessionID.descending()
const exit = yield* HttpSessionError.mapBusy(Effect.fail(new Session.BusyError({ sessionID }))).pipe(Effect.exit)
expect(Exit.isFailure(exit)).toBe(true)
if (Exit.isFailure(exit)) {
expect(Cause.squash(exit.cause)).toMatchObject({
_tag: "SessionBusyError",
sessionID,
message: `Session is busy: ${sessionID}`,
})
}
}),
)
it.instance(
"returns declared not found errors for read routes",
() =>