@@ -279,6 +279,20 @@ function createQaGatewayChildLogCollector() {
279279 } ;
280280}
281281
282+ function monitorQaGatewayChildSpawnError (
283+ child : ChildProcess ,
284+ output : { push ( chunk : Buffer ) : void } ,
285+ ) {
286+ let spawnError : unknown = null ;
287+ child . once ( "error" , ( error ) => {
288+ spawnError = error ;
289+ output . push (
290+ Buffer . from ( `[qa-lab] gateway child process error: ${ formatErrorMessage ( error ) } \n` ) ,
291+ ) ;
292+ } ) ;
293+ return ( ) => spawnError ;
294+ }
295+
282296async function fetchLocalGatewayHealth ( params : {
283297 baseUrl : string ;
284298 healthPath : "/readyz" | "/healthz" ;
@@ -487,10 +501,19 @@ async function waitForGatewayReady(params: {
487501 exitCode : number | null ;
488502 signalCode : NodeJS . Signals | null ;
489503 } ;
504+ getSpawnError ?: ( ) => unknown ;
490505 timeoutMs ?: number ;
491506} ) {
492507 const startedAt = Date . now ( ) ;
493508 while ( Date . now ( ) - startedAt < ( params . timeoutMs ?? 60_000 ) ) {
509+ const spawnError = params . getSpawnError ?.( ) ;
510+ if ( spawnError ) {
511+ throw new QaSuiteInfraError (
512+ "gateway_startup_unhealthy" ,
513+ `gateway failed to spawn: ${ formatErrorMessage ( spawnError ) } \n${ params . logs ( ) } ` ,
514+ { cause : spawnError } ,
515+ ) ;
516+ }
494517 if ( params . child . exitCode !== null || params . child . signalCode !== null ) {
495518 throw new QaSuiteInfraError (
496519 "gateway_startup_unhealthy" ,
@@ -768,12 +791,14 @@ export async function startQaGatewayChild(params: {
768791 stderrLog . write ( buffer ) ;
769792 } ) ;
770793 child = attemptChild ;
794+ const getAttemptSpawnError = monitorQaGatewayChildSpawnError ( attemptChild , output ) ;
771795
772796 try {
773797 await waitForGatewayReady ( {
774798 baseUrl,
775799 logs,
776800 child : attemptChild ,
801+ getSpawnError : getAttemptSpawnError ,
777802 timeoutMs : 120_000 ,
778803 } ) ;
779804 const attemptRpcClient = await startQaGatewayRpcClient ( {
@@ -805,6 +830,7 @@ export async function startQaGatewayChild(params: {
805830 baseUrl,
806831 logs,
807832 child : attemptChild ,
833+ getSpawnError : getAttemptSpawnError ,
808834 timeoutMs : QA_GATEWAY_CHILD_RPC_RETRY_HEALTH_TIMEOUT_MS ,
809835 } ) ;
810836 }
@@ -871,12 +897,14 @@ export async function startQaGatewayChild(params: {
871897 output . push ( buffer ) ;
872898 stderrLog . write ( buffer ) ;
873899 } ) ;
900+ const getNextSpawnError = monitorQaGatewayChildSpawnError ( nextChild , output ) ;
874901
875902 try {
876903 await waitForGatewayReady ( {
877904 baseUrl,
878905 logs,
879906 child : nextChild ,
907+ getSpawnError : getNextSpawnError ,
880908 timeoutMs : 120_000 ,
881909 } ) ;
882910 const nextRpcClient = await startQaGatewayRpcClient ( {
@@ -908,6 +936,7 @@ export async function startQaGatewayChild(params: {
908936 baseUrl,
909937 logs,
910938 child : nextChild ,
939+ getSpawnError : getNextSpawnError ,
911940 timeoutMs : 15_000 ,
912941 } ) ;
913942 }
0 commit comments