@@ -412,6 +412,23 @@ async function cancelRun() {
412412 return true
413413}
414414
415+ async function raceRunOutcome ( runPromise , timeout ) {
416+ const pausedPromise = new Promise ( resolve => pauseEvents . once ( 'paused' , ( ) => resolve ( 'paused' ) ) )
417+ const completedPromise = runPromise . then ( ( ) => 'completed' , ( ) => 'completed' )
418+ let timeoutId
419+ const timeoutPromise = new Promise ( ( _ , reject ) => {
420+ timeoutId = setTimeout ( ( ) => reject ( new Error ( `Timeout after ${ timeout } ms` ) ) , timeout )
421+ } )
422+ try {
423+ return { outcome : await Promise . race ( [ completedPromise , pausedPromise , timeoutPromise ] ) }
424+ } catch ( err ) {
425+ await cancelRun ( )
426+ return { outcome : 'aborted' , error : err . message }
427+ } finally {
428+ clearTimeout ( timeoutId )
429+ }
430+ }
431+
415432async function closeBrowser ( ) {
416433 if ( ! containerInitialized ) return
417434 await cancelRun ( )
@@ -1027,26 +1044,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
10271044 } ) ( )
10281045 pendingRunPromise = runPromise
10291046
1030- const pausedPromise = new Promise ( resolve => pauseEvents . once ( 'paused' , ( ) => resolve ( 'paused' ) ) )
1031- const completedPromise = runPromise . then ( ( ) => 'completed' , ( ) => 'completed' )
1032-
1033- let timeoutId
1034- const timeoutPromise = new Promise ( ( _ , reject ) => {
1035- timeoutId = setTimeout ( ( ) => reject ( new Error ( `Timeout after ${ timeout } ms` ) ) , timeout )
1036- } )
1037-
1038- let which
1039- try {
1040- which = await Promise . race ( [ completedPromise , pausedPromise , timeoutPromise ] )
1041- } catch ( err ) {
1042- await cancelRun ( )
1047+ const { outcome, error : abortError } = await raceRunOutcome ( runPromise , timeout )
1048+ if ( outcome === 'aborted' ) {
10431049 await startShellSession ( )
1044- return { content : [ { type : 'text' , text : JSON . stringify ( { status : 'failed' , file : testFile , error : err . message } , null , 2 ) } ] }
1045- } finally {
1046- clearTimeout ( timeoutId )
1050+ return { content : [ { type : 'text' , text : JSON . stringify ( { status : 'failed' , file : testFile , error : abortError } , null , 2 ) } ] }
10471051 }
10481052
1049- if ( which === 'paused' ) {
1053+ if ( outcome === 'paused' ) {
10501054 const page = await gatherPageBrief ( )
10511055 return {
10521056 content : [ {
@@ -1134,26 +1138,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
11341138 } ) ( )
11351139 pendingRunPromise = runPromise
11361140
1137- const pausedPromise = new Promise ( resolve => pauseEvents . once ( 'paused' , ( ) => resolve ( 'paused' ) ) )
1138- const completedPromise = runPromise . then ( ( ) => 'completed' , ( ) => 'completed' )
1139-
1140- let timeoutId
1141- const timeoutPromise = new Promise ( ( _ , reject ) => {
1142- timeoutId = setTimeout ( ( ) => reject ( new Error ( `Timeout after ${ timeout } ms` ) ) , timeout )
1143- } )
1144-
1145- let which
1146- try {
1147- which = await Promise . race ( [ completedPromise , pausedPromise , timeoutPromise ] )
1148- } catch ( err ) {
1149- await cancelRun ( )
1141+ const { outcome, error : abortError } = await raceRunOutcome ( runPromise , timeout )
1142+ if ( outcome === 'aborted' ) {
11501143 await startShellSession ( )
1151- return { content : [ { type : 'text' , text : JSON . stringify ( { status : 'failed' , file : testFile , error : err . message } , null , 2 ) } ] }
1152- } finally {
1153- clearTimeout ( timeoutId )
1144+ return { content : [ { type : 'text' , text : JSON . stringify ( { status : 'failed' , file : testFile , error : abortError } , null , 2 ) } ] }
11541145 }
11551146
1156- if ( which === 'paused' ) {
1147+ if ( outcome === 'paused' ) {
11571148 const page = await gatherPageBrief ( )
11581149 return {
11591150 content : [ {
0 commit comments