@@ -64,8 +64,45 @@ const configuredAuthFailureCases: Array<{
6464] ;
6565
6666describe ( "CodexEventHandler - auth error events" , ( ) => {
67+ it ( "keeps the prompt alive for a retryable HTTP 401" , async ( ) => {
68+ const { result : response , updates} = await runPromptWithError ( createTestSessionState ( {
69+ sessionId : "retrying-session" ,
70+ account : { type : "apiKey" } ,
71+ } ) , {
72+ message : "Reconnecting after provider returned 401" ,
73+ codexErrorInfo : {
74+ responseStreamDisconnected : {
75+ httpStatusCode : 401 ,
76+ } ,
77+ } ,
78+ additionalDetails : "HTTP status 401" ,
79+ } , true ) ;
80+
81+ expect ( response ) . toMatchObject ( {
82+ stopReason : "end_turn" ,
83+ } ) ;
84+ expect ( updates ) . toEqual ( [ {
85+ sessionUpdate : "session_info_update" ,
86+ _meta : {
87+ codex : {
88+ error : {
89+ message : "Reconnecting after provider returned 401" ,
90+ codexErrorInfo : {
91+ responseStreamDisconnected : {
92+ httpStatusCode : 401 ,
93+ } ,
94+ } ,
95+ additionalDetails : "HTTP status 401" ,
96+ turnId : "turn-id" ,
97+ willRetry : true ,
98+ } ,
99+ } ,
100+ } ,
101+ } ] ) ;
102+ } ) ;
103+
67104 it ( "returns AuthRequired for auth errors when no auth is configured" , async ( ) => {
68- const error = await runPromptWithError ( createTestSessionState ( {
105+ const { result : error } = await runPromptWithError ( createTestSessionState ( {
69106 sessionId : "unauthenticated-session" ,
70107 account : null ,
71108 authConfigured : false ,
@@ -88,7 +125,7 @@ describe("CodexEventHandler - auth error events", () => {
88125 it . each ( configuredAuthFailureCases ) (
89126 "returns InternalError with details for $name when auth is configured" ,
90127 async ( { turnError, sessionOverrides, expectedData} ) => {
91- const error = await runPromptWithError ( createTestSessionState ( {
128+ const { result : error } = await runPromptWithError ( createTestSessionState ( {
92129 sessionId : "authenticated-session" ,
93130 account : { type : "apiKey" } ,
94131 ...sessionOverrides ,
@@ -109,7 +146,8 @@ describe("CodexEventHandler - auth error events", () => {
109146async function runPromptWithError (
110147 sessionState : SessionState ,
111148 turnError : ErrorNotification [ "error" ] ,
112- ) : Promise < unknown > {
149+ willRetry = false ,
150+ ) : Promise < { result : unknown ; updates : unknown [ ] } > {
113151 const mockFixture = createCodexMockTestFixture ( ) ;
114152 const codexAcpAgent = mockFixture . getCodexAcpAgent ( ) ;
115153 const codexAppServerClient = mockFixture . getCodexAppServerClient ( ) ;
@@ -134,7 +172,7 @@ async function runPromptWithError(
134172 params : {
135173 threadId : sessionState . sessionId ,
136174 turnId : "turn-id" ,
137- willRetry : false ,
175+ willRetry,
138176 error : turnError ,
139177 } ,
140178 } ) ;
@@ -144,14 +182,16 @@ async function runPromptWithError(
144182 turn : createTurn ( "completed" ) ,
145183 } ) ;
146184
147- let caughtError : unknown ;
185+ let result : unknown ;
148186 try {
149- await promptPromise ;
187+ result = await promptPromise ;
150188 } catch ( error ) {
151- caughtError = error ;
189+ result = error ;
152190 }
153- expect ( caughtError ) . toBeDefined ( ) ;
154- return caughtError ;
191+ return {
192+ result,
193+ updates : mockFixture . getAcpConnectionEvents ( [ ] ) . map ( event => event . args [ 0 ] . update ) ,
194+ } ;
155195}
156196
157197function createTurn ( status : "inProgress" | "completed" ) {
0 commit comments