feat(KB-641): merge kb/kb-641 (auto-resolved)
- feat(KB-641): complete Step 5 — add changeset - feat(KB-641): complete Step 2 — update terminal route errors
This commit is contained in:
@@ -4736,9 +4736,13 @@ describe("Terminal session routes", () => {
|
||||
});
|
||||
|
||||
describe("POST /api/terminal/sessions", () => {
|
||||
it("returns 503 when max sessions reached (session is null)", async () => {
|
||||
it("returns 503 with specific max sessions error", async () => {
|
||||
const mockService = {
|
||||
createSession: vi.fn().mockResolvedValue(null),
|
||||
createSession: vi.fn().mockResolvedValue({
|
||||
success: false,
|
||||
code: "max_sessions",
|
||||
error: "Maximum terminal sessions reached. Please close an existing terminal and try again.",
|
||||
}),
|
||||
};
|
||||
vi.spyOn(terminalServiceModule, "getTerminalService").mockReturnValue(mockService as any);
|
||||
|
||||
@@ -4751,7 +4755,69 @@ describe("Terminal session routes", () => {
|
||||
);
|
||||
|
||||
expect(res.status).toBe(503);
|
||||
expect(res.body.error).toContain("Max sessions");
|
||||
expect(res.body).toEqual({
|
||||
error: "Maximum terminal sessions reached. Please close an existing terminal and try again.",
|
||||
code: "max_sessions",
|
||||
});
|
||||
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it.each([
|
||||
["invalid_shell", 400, "Shell not allowed. Please use a supported shell (bash, zsh, sh, cmd, powershell)."],
|
||||
["pty_load_failed", 503, "Terminal service unavailable. The PTY module could not be loaded."],
|
||||
["pty_spawn_failed", 500, "Failed to start terminal shell process."],
|
||||
] as const)("returns %s errors with the correct status and body", async (code, status, error) => {
|
||||
const mockService = {
|
||||
createSession: vi.fn().mockResolvedValue({
|
||||
success: false,
|
||||
code,
|
||||
error,
|
||||
}),
|
||||
};
|
||||
vi.spyOn(terminalServiceModule, "getTerminalService").mockReturnValue(mockService as any);
|
||||
|
||||
const res = await REQUEST(
|
||||
buildApp(),
|
||||
"POST",
|
||||
"/api/terminal/sessions",
|
||||
JSON.stringify({ shell: "/bad/shell" }),
|
||||
{ "Content-Type": "application/json" },
|
||||
);
|
||||
|
||||
expect(res.status).toBe(status);
|
||||
expect(res.body).toEqual({ error, code });
|
||||
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("returns 201 for a successful session creation", async () => {
|
||||
const mockService = {
|
||||
createSession: vi.fn().mockResolvedValue({
|
||||
success: true,
|
||||
session: {
|
||||
id: "term-123",
|
||||
shell: "/bin/zsh",
|
||||
cwd: "/fake/root",
|
||||
},
|
||||
}),
|
||||
};
|
||||
vi.spyOn(terminalServiceModule, "getTerminalService").mockReturnValue(mockService as any);
|
||||
|
||||
const res = await REQUEST(
|
||||
buildApp(),
|
||||
"POST",
|
||||
"/api/terminal/sessions",
|
||||
JSON.stringify({}),
|
||||
{ "Content-Type": "application/json" },
|
||||
);
|
||||
|
||||
expect(res.status).toBe(201);
|
||||
expect(res.body).toEqual({
|
||||
sessionId: "term-123",
|
||||
shell: "/bin/zsh",
|
||||
cwd: "/fake/root",
|
||||
});
|
||||
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
@@ -4145,21 +4145,28 @@ export function createApiRoutes(store: TaskStore, options?: ServerOptions): Rout
|
||||
const { cwd, cols, rows } = req.body;
|
||||
const terminalService = getTerminalService(store.getRootDir());
|
||||
|
||||
const session = await terminalService.createSession({
|
||||
const result = await terminalService.createSession({
|
||||
cwd,
|
||||
cols: typeof cols === "number" ? cols : undefined,
|
||||
rows: typeof rows === "number" ? rows : undefined,
|
||||
});
|
||||
|
||||
if (!session) {
|
||||
res.status(503).json({ error: "Failed to create session. Max sessions may be reached." });
|
||||
if (!result.success) {
|
||||
const statusByCode = {
|
||||
max_sessions: 503,
|
||||
invalid_shell: 400,
|
||||
pty_load_failed: 503,
|
||||
pty_spawn_failed: 500,
|
||||
} as const;
|
||||
|
||||
res.status(statusByCode[result.code]).json({ error: result.error, code: result.code });
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(201).json({
|
||||
sessionId: session.id,
|
||||
shell: session.shell,
|
||||
cwd: session.cwd,
|
||||
sessionId: result.session.id,
|
||||
shell: result.session.shell,
|
||||
cwd: result.session.cwd,
|
||||
});
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: err.message || "Failed to create terminal session" });
|
||||
|
||||
Reference in New Issue
Block a user