Skip to content

Commit d1339ed

Browse files
committed
fix: fall back when Daytona session API is unavailable
1 parent b0c0477 commit d1339ed

3 files changed

Lines changed: 20 additions & 11 deletions

File tree

packages/core/src/sandbox/daytona-sandbox.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,13 +340,17 @@ export class DaytonaSandbox implements Sandbox {
340340
// `maxBuffer` and load unbounded stdout — the inconsistency
341341
// Cursor Bugbot flagged on PR #2748.
342342
const maxBuffer = options.maxBuffer ?? EXEC_OUTPUT_MAX_BUFFER;
343-
if (options.signal) {
343+
const processApi = this.handle.process as DaytonaProcessApi;
344+
if (options.signal?.aborted) {
345+
return cancelledExecResult();
346+
}
347+
if (options.signal && this.hasSessionApi(processApi)) {
344348
return await this.execWithSession(fullCommand, {
345349
...options,
346350
maxBuffer,
347351
});
348352
}
349-
const result = await this.handle.process.executeCommand(fullCommand);
353+
const result = await processApi.executeCommand(fullCommand);
350354
return {
351355
stdout: truncateOutput(result.result, maxBuffer),
352356
stderr: "",

test/packages/core/daytona-sandbox-edge-cases.test.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ describe("DaytonaSandbox Edge Cases", () => {
186186
});
187187

188188
describe("abortable exec fallbacks", () => {
189-
it("fails when abortable execution is requested without session APIs", async () => {
189+
it("falls back to executeCommand when abortable execution lacks session APIs", async () => {
190190
const handle = createMockHandle();
191191
const sandbox = await createTestSandbox(handle);
192192
const controller = new AbortController();
@@ -197,10 +197,12 @@ describe("DaytonaSandbox Edge Cases", () => {
197197

198198
expect(result).toEqual({
199199
stdout: "",
200-
stderr: "Daytona abortable execution requires session API support",
201-
exitCode: 1,
200+
stderr: "",
201+
exitCode: 0,
202202
});
203-
expect(handle.process.executeCommand).not.toHaveBeenCalled();
203+
expect(handle.process.executeCommand).toHaveBeenCalledWith(
204+
"gh pr view 1",
205+
);
204206
});
205207
});
206208

test/packages/core/daytona-sandbox.test.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ describe("DaytonaSandbox", () => {
394394
expect(handle.process.executeCommand).not.toHaveBeenCalled();
395395
});
396396

397-
it("fails before fallback executeCommand when abortable sessions are unavailable", async () => {
397+
it("falls back to executeCommand when abortable sessions are unavailable", async () => {
398398
const handle = createMockHandle();
399399
handle.process.createSession = undefined as never;
400400
handle.process.deleteSession = undefined as never;
@@ -408,11 +408,14 @@ describe("DaytonaSandbox", () => {
408408
signal: controller.signal,
409409
});
410410

411-
expect(result.exitCode).toBe(1);
412-
expect(result.stderr).toContain(
413-
"Daytona abortable execution requires session API support",
411+
expect(result).toEqual({
412+
stdout: "output\n",
413+
stderr: "",
414+
exitCode: 0,
415+
});
416+
expect(handle.process.executeCommand).toHaveBeenCalledWith(
417+
"gh pr view 1",
414418
);
415-
expect(handle.process.executeCommand).not.toHaveBeenCalled();
416419
});
417420

418421
it("deletes the remote session when the abort signal fires", async () => {

0 commit comments

Comments
 (0)