diff --git a/src/CodexAcpServer.ts b/src/CodexAcpServer.ts index 0865c984..058ef099 100644 --- a/src/CodexAcpServer.ts +++ b/src/CodexAcpServer.ts @@ -168,6 +168,23 @@ export class CodexAcpServer implements acp.Agent { } async getOrCreateSession(request: acp.NewSessionRequest | acp.ResumeSessionRequest): Promise<[SessionId, SessionModelState, SessionModeState]> { + try { + return await this.tryCreateSession(request); + } catch (e) { + const error = e instanceof Error ? e : new Error(String(e)); + await this.handleError(error); + throw e; + } + } + + async handleError(e: Error){ + if (e.message.includes("log out")) { + await this.runWithProcessCheck(() => this.codexAcpClient.logout()); + throw RequestError.internalError(`${(e.message)}\n\nYou have been logged out. Please try again.`); + } + } + + async tryCreateSession(request: acp.NewSessionRequest | acp.ResumeSessionRequest): Promise<[SessionId, SessionModelState, SessionModeState]> { await this.checkAuthorization(); const requestedMcpServers = request.mcpServers ?? []; const mcpServerStartupVersion = requestedMcpServers.length > 0 diff --git a/src/__tests__/CodexACPAgent/new-session-logout.test.ts b/src/__tests__/CodexACPAgent/new-session-logout.test.ts new file mode 100644 index 00000000..88835ef1 --- /dev/null +++ b/src/__tests__/CodexACPAgent/new-session-logout.test.ts @@ -0,0 +1,23 @@ +import {describe, expect, it, vi} from "vitest"; +import {createCodexMockTestFixture} from "../acp-test-utils"; + +describe("New session logout handling", () => { + it("logs out when newSession fails with an error containing log out", async () => { + const fixture = createCodexMockTestFixture(); + const codexAcpAgent = fixture.getCodexAcpAgent(); + const codexAcpClient = fixture.getCodexAcpClient(); + const codexAppServerClient = fixture.getCodexAppServerClient(); + vi.spyOn(codexAcpClient, "authRequired").mockResolvedValue(false); + + const errorMessage = `Internal error: "failed to reload config: Your access token could not be refreshed because your refresh token was already used. Please log out and sign in again."`; + vi.spyOn(codexAppServerClient, "threadStart").mockRejectedValue(new Error(errorMessage)); + + const logoutSpy = vi.spyOn(codexAcpClient, "logout").mockResolvedValue(); + + await expect(codexAcpAgent.newSession({cwd: "", mcpServers: []})) + .rejects.toMatchObject({ + data: expect.stringContaining("You have been logged out. Please try again."), + }); + expect(logoutSpy).toHaveBeenCalledOnce(); + }); +});