@@ -512,8 +512,10 @@ describe("createChildAdapter", () => {
512512 expect ( second ) . toHaveBeenCalledWith ( "second" ) ;
513513 } ) ;
514514
515- it ( "suppresses stream errors on stdout and stderr to prevent unhandled error crashes" , async ( ) => {
516- const { child } = createStubChild ( 6666 ) ;
515+ it ( "guards stream errors before output listeners are registered" , async ( ) => {
516+ vi . useFakeTimers ( ) ;
517+ setPlatform ( "win32" ) ;
518+ const { child, emitExit } = createStubChild ( 6666 ) ;
517519 spawnWithFallbackMock . mockResolvedValue ( {
518520 child,
519521 usedFallback : false ,
@@ -523,17 +525,28 @@ describe("createChildAdapter", () => {
523525 stdinMode : "pipe-open" ,
524526 } ) ;
525527
526- // Register stdout/stderr listeners to install the error handlers
527- adapter . onStdout ( ( ) => { } ) ;
528- adapter . onStderr ( ( ) => { } ) ;
529-
530- // Emitting errors on the streams must not crash the process.
531- // If the noop error handlers were missing, Node would throw
532- // an unhandled 'error' event and crash the test runner.
533528 const stdoutErr = new Error ( "simulated stdout pipe error" ) ;
534529 const stderrErr = new Error ( "simulated stderr pipe error" ) ;
530+ const settled = vi . fn ( ) ;
531+ void adapter . wait ( ) . then ( settled ) ;
535532
533+ emitExit ( 0 , null ) ;
536534 expect ( ( ) => child . stdout ?. emit ( "error" , stdoutErr ) ) . not . toThrow ( ) ;
537535 expect ( ( ) => child . stderr ?. emit ( "error" , stderrErr ) ) . not . toThrow ( ) ;
536+ await vi . advanceTimersByTimeAsync ( 300 ) ;
537+ expect ( settled ) . not . toHaveBeenCalled ( ) ;
538+
539+ adapter . onStdout ( ( ) => { } ) ;
540+ adapter . onStdout ( ( ) => { } ) ;
541+ adapter . onStderr ( ( ) => { } ) ;
542+ adapter . onStderr ( ( ) => { } ) ;
543+
544+ expect ( child . stdout ?. listenerCount ( "error" ) ) . toBe ( 1 ) ;
545+ expect ( child . stderr ?. listenerCount ( "error" ) ) . toBe ( 1 ) ;
546+
547+ child . stdout ?. emit ( "close" ) ;
548+ child . stderr ?. emit ( "close" ) ;
549+ await vi . advanceTimersByTimeAsync ( 0 ) ;
550+ expect ( settled ) . toHaveBeenCalledWith ( { code : 0 , signal : null } ) ;
538551 } ) ;
539552} ) ;
0 commit comments