Skip to content

Commit c5cdfdf

Browse files
committed
fixes
1 parent 71c8ee6 commit c5cdfdf

File tree

3 files changed

+68
-13
lines changed

3 files changed

+68
-13
lines changed

apps/twig/src/renderer/features/sessions/service/service.test.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,17 @@ vi.mock(
9090
() => mockSessionConfigStore,
9191
);
9292

93+
const mockAdapterFns = vi.hoisted(() => ({
94+
setAdapter: vi.fn(),
95+
getAdapter: vi.fn(),
96+
removeAdapter: vi.fn(),
97+
}));
98+
9399
const mockSessionAdapterStore = vi.hoisted(() => ({
94100
useSessionAdapterStore: {
95101
getState: vi.fn(() => ({
96102
adaptersByRunId: {},
97-
setAdapter: vi.fn(),
98-
getAdapter: vi.fn(),
99-
removeAdapter: vi.fn(),
103+
...mockAdapterFns,
100104
})),
101105
},
102106
}));

apps/twig/src/renderer/features/sessions/service/service.ts

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,28 @@ export class SessionService {
366366
taskId,
367367
taskRunId,
368368
});
369-
await this.recreateSession(
370-
taskRunId,
371-
taskId,
372-
taskTitle,
373-
repoPath,
374-
auth,
375-
);
369+
try {
370+
await this.recreateSession(
371+
taskRunId,
372+
taskId,
373+
taskTitle,
374+
repoPath,
375+
auth,
376+
);
377+
} catch (recreateError) {
378+
log.error("Failed to recreate session after null reconnect", {
379+
taskId,
380+
error:
381+
recreateError instanceof Error
382+
? recreateError.message
383+
: String(recreateError),
384+
});
385+
this.setErrorSession(
386+
taskId,
387+
taskRunId,
388+
"Failed to start a new session. Please try again.",
389+
);
390+
}
376391
}
377392
} catch (error) {
378393
const errorMessage =
@@ -381,15 +396,39 @@ export class SessionService {
381396
taskId,
382397
error: errorMessage,
383398
});
384-
await this.recreateSession(taskRunId, taskId, taskTitle, repoPath, auth);
399+
try {
400+
await this.recreateSession(
401+
taskRunId,
402+
taskId,
403+
taskTitle,
404+
repoPath,
405+
auth,
406+
);
407+
} catch (recreateError) {
408+
log.error("Failed to recreate session after reconnect error", {
409+
taskId,
410+
error:
411+
recreateError instanceof Error
412+
? recreateError.message
413+
: String(recreateError),
414+
});
415+
this.setErrorSession(
416+
taskId,
417+
taskRunId,
418+
errorMessage || "Failed to reconnect. Please try again.",
419+
);
420+
}
385421
}
386422
}
387423

388424
private async teardownSession(taskRunId: string): Promise<void> {
389425
try {
390426
await trpcVanilla.agent.cancel.mutate({ sessionId: taskRunId });
391-
} catch {
392-
// Best-effort — session may already be gone on the main process
427+
} catch (error) {
428+
log.debug("Cancel during teardown failed (session may already be gone)", {
429+
taskRunId,
430+
error: error instanceof Error ? error.message : String(error),
431+
});
393432
}
394433

395434
this.unsubscribeFromChannel(taskRunId);
@@ -398,6 +437,17 @@ export class SessionService {
398437
removePersistedConfigOptions(taskRunId);
399438
}
400439

440+
private setErrorSession(
441+
taskId: string,
442+
taskRunId: string,
443+
errorMessage: string,
444+
): void {
445+
const session = this.createBaseSession(taskRunId, taskId, "");
446+
session.status = "error";
447+
session.errorMessage = errorMessage;
448+
sessionStoreSetters.setSession(session);
449+
}
450+
401451
private async recreateSession(
402452
oldTaskRunId: string,
403453
taskId: string,

apps/twig/src/renderer/features/task-detail/components/WorkspaceSetupPrompt.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export function WorkspaceSetupPrompt({
4848
} catch (error) {
4949
log.error("Failed to set up workspace", { error });
5050
toast.error("Failed to set up workspace. Please try again.");
51+
} finally {
5152
setSelectedPath("");
5253
setIsSettingUp(false);
5354
}

0 commit comments

Comments
 (0)