Skip to content

Commit 75df8f2

Browse files
committed
fixes
1 parent 028c80f commit 75df8f2

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
@@ -360,13 +360,28 @@ export class SessionService {
360360
taskId,
361361
taskRunId,
362362
});
363-
await this.recreateSession(
364-
taskRunId,
365-
taskId,
366-
taskTitle,
367-
repoPath,
368-
auth,
369-
);
363+
try {
364+
await this.recreateSession(
365+
taskRunId,
366+
taskId,
367+
taskTitle,
368+
repoPath,
369+
auth,
370+
);
371+
} catch (recreateError) {
372+
log.error("Failed to recreate session after null reconnect", {
373+
taskId,
374+
error:
375+
recreateError instanceof Error
376+
? recreateError.message
377+
: String(recreateError),
378+
});
379+
this.setErrorSession(
380+
taskId,
381+
taskRunId,
382+
"Failed to start a new session. Please try again.",
383+
);
384+
}
370385
}
371386
} catch (error) {
372387
const errorMessage =
@@ -375,15 +390,39 @@ export class SessionService {
375390
taskId,
376391
error: errorMessage,
377392
});
378-
await this.recreateSession(taskRunId, taskId, taskTitle, repoPath, auth);
393+
try {
394+
await this.recreateSession(
395+
taskRunId,
396+
taskId,
397+
taskTitle,
398+
repoPath,
399+
auth,
400+
);
401+
} catch (recreateError) {
402+
log.error("Failed to recreate session after reconnect error", {
403+
taskId,
404+
error:
405+
recreateError instanceof Error
406+
? recreateError.message
407+
: String(recreateError),
408+
});
409+
this.setErrorSession(
410+
taskId,
411+
taskRunId,
412+
errorMessage || "Failed to reconnect. Please try again.",
413+
);
414+
}
379415
}
380416
}
381417

382418
private async teardownSession(taskRunId: string): Promise<void> {
383419
try {
384420
await trpcVanilla.agent.cancel.mutate({ sessionId: taskRunId });
385-
} catch {
386-
// Best-effort — session may already be gone on the main process
421+
} catch (error) {
422+
log.debug("Cancel during teardown failed (session may already be gone)", {
423+
taskRunId,
424+
error: error instanceof Error ? error.message : String(error),
425+
});
387426
}
388427

389428
this.unsubscribeFromChannel(taskRunId);
@@ -392,6 +431,17 @@ export class SessionService {
392431
removePersistedConfigOptions(taskRunId);
393432
}
394433

434+
private setErrorSession(
435+
taskId: string,
436+
taskRunId: string,
437+
errorMessage: string,
438+
): void {
439+
const session = this.createBaseSession(taskRunId, taskId, "");
440+
session.status = "error";
441+
session.errorMessage = errorMessage;
442+
sessionStoreSetters.setSession(session);
443+
}
444+
395445
private async recreateSession(
396446
oldTaskRunId: string,
397447
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)