@@ -352,8 +352,8 @@ async function main() {
352352 "CLI boot after erase" ,
353353 ( ) =>
354354 retrySimdeckJson ( [ "boot" , simulatorUDID ] , "CLI boot after erase" , {
355- attempts : 3 ,
356- delayMs : 3_000 ,
355+ attempts : process . env . CI === "true" ? 4 : 3 ,
356+ delayMs : 5_000 ,
357357 timeoutMs : 180_000 ,
358358 } ) ,
359359 { phase : phaseSimulatorLifecycle } ,
@@ -744,8 +744,8 @@ function startServer() {
744744 ) ;
745745}
746746
747- async function waitForHealth ( ) {
748- const deadline = Date . now ( ) + 30_000 ;
747+ async function waitForHealth ( options = { } ) {
748+ const deadline = Date . now ( ) + ( options . timeoutMs ?? 30_000 ) ;
749749 while ( Date . now ( ) < deadline ) {
750750 try {
751751 const health = await httpJson ( "GET" , "/api/health" ) ;
@@ -766,6 +766,7 @@ function simdeckJson(args, options = {}) {
766766async function retrySimdeckJson ( args , label , options = { } ) {
767767 const attempts = options . attempts ?? 6 ;
768768 const delayMs = options . delayMs ?? 2_000 ;
769+ const healthTimeoutMs = options . healthTimeoutMs ?? 60_000 ;
769770 let lastError ;
770771 for ( let attempt = 1 ; attempt <= attempts ; attempt += 1 ) {
771772 try {
@@ -775,6 +776,16 @@ async function retrySimdeckJson(args, label, options = {}) {
775776 if ( attempt === attempts ) {
776777 break ;
777778 }
779+ if ( isServiceConnectionError ( error ) ) {
780+ logStep (
781+ `${ label } lost service connection on attempt ${ attempt } ; waiting for health before retry` ,
782+ ) ;
783+ try {
784+ await waitForHealth ( { timeoutMs : healthTimeoutMs } ) ;
785+ } catch ( healthError ) {
786+ lastError = healthError ;
787+ }
788+ }
778789 await sleep ( delayMs ) ;
779790 }
780791 }
@@ -786,6 +797,7 @@ async function retrySimdeckJson(args, label, options = {}) {
786797async function retrySimdeckText ( args , label , options = { } ) {
787798 const attempts = options . attempts ?? 6 ;
788799 const delayMs = options . delayMs ?? 2_000 ;
800+ const healthTimeoutMs = options . healthTimeoutMs ?? 60_000 ;
789801 let lastError ;
790802 for ( let attempt = 1 ; attempt <= attempts ; attempt += 1 ) {
791803 try {
@@ -795,6 +807,16 @@ async function retrySimdeckText(args, label, options = {}) {
795807 if ( attempt === attempts ) {
796808 break ;
797809 }
810+ if ( isServiceConnectionError ( error ) ) {
811+ logStep (
812+ `${ label } lost service connection on attempt ${ attempt } ; waiting for health before retry` ,
813+ ) ;
814+ try {
815+ await waitForHealth ( { timeoutMs : healthTimeoutMs } ) ;
816+ } catch ( healthError ) {
817+ lastError = healthError ;
818+ }
819+ }
798820 await sleep ( delayMs ) ;
799821 }
800822 }
@@ -803,6 +825,16 @@ async function retrySimdeckText(args, label, options = {}) {
803825 ) ;
804826}
805827
828+ function isServiceConnectionError ( error ) {
829+ const message = String ( error ?. message ?? error ) . toLowerCase ( ) ;
830+ return (
831+ message . includes ( "connect to simdeck service" ) ||
832+ message . includes ( "connection refused" ) ||
833+ message . includes ( "connection reset" ) ||
834+ message . includes ( "failed to connect" )
835+ ) ;
836+ }
837+
806838async function retrySimdeckTextUntil (
807839 args ,
808840 label ,
0 commit comments