@@ -51,6 +51,9 @@ export class MongoBinaryDownload {
5151 /** These options are kind of raw, they are not run through DryMongoBinary.generateOptions */
5252 binaryOpts : Required < MongoBinaryOpts > ;
5353
54+ /** Determines if direct stdio should be done, or repeated `console.log`s */
55+ public isTTY : boolean = false ;
56+
5457 constructor ( opts : MongoBinaryOpts ) {
5558 assertion ( typeof opts . downloadDir === 'string' , new Error ( 'An DownloadDir must be specified!' ) ) ;
5659 const version = opts . version ?? resolveConfig ( ResolveConfigVariables . VERSION ) ;
@@ -76,6 +79,8 @@ export class MongoBinaryDownload {
7679 totalMb : 0 ,
7780 lastPrintedAt : 0 ,
7881 } ;
82+
83+ this . isTTY = process . stdout . isTTY ;
7984 }
8085
8186 /**
@@ -385,7 +390,8 @@ export class MongoBinaryDownload {
385390 downloadLocation : string ,
386391 tempDownloadLocation : string ,
387392 maxRetries ?: number ,
388- baseDelay : number = 1000
393+ baseDelay : number = 1000 ,
394+ timeout : number = 60000
389395 ) : Promise < string > {
390396 log ( 'httpDownload' ) ;
391397 const downloadUrl = this . assignDownloadingURL ( url ) ;
@@ -405,15 +411,17 @@ export class MongoBinaryDownload {
405411 ? retriesFromConfig
406412 : 3 ;
407413
408- for ( let attempt = 0 ; attempt <= retries ; attempt ++ ) {
414+ // start at 1 attempt as there are basically no 0 attemps
415+ for ( let attempt = 1 ; attempt <= retries ; attempt ++ ) {
409416 try {
410417 return await this . attemptDownload (
411418 url ,
412419 useHttpsOptions ,
413420 downloadLocation ,
414421 tempDownloadLocation ,
415422 downloadUrl ,
416- httpOptions
423+ httpOptions ,
424+ timeout
417425 ) ;
418426 } catch ( error : any ) {
419427 const shouldRetry =
@@ -464,7 +472,8 @@ export class MongoBinaryDownload {
464472 downloadLocation : string ,
465473 tempDownloadLocation : string ,
466474 downloadUrl : string ,
467- httpOptions : RequestOptions
475+ httpOptions : RequestOptions ,
476+ timeout : number = 60000
468477 ) : Promise < string > {
469478 /** Offset to resume from; for now a non-0 value indicates to use file "append" mode */
470479 let offset = 0 ;
@@ -560,6 +569,15 @@ export class MongoBinaryDownload {
560569 // not using option "start" as we already open in "append" mode
561570 const fileStream = createWriteStream ( tempDownloadLocation , { /* start: offset, */ flags } ) ;
562571
572+ fileStream . on ( 'error' , ( err ) => {
573+ response . destroy ( ) ;
574+
575+ // use the code if available, otherwise use the entire message
576+ const code = ( err as any ) ?. code ?? err . message ;
577+
578+ reject ( new DownloadError ( downloadUrl , err . message , code ) ) ;
579+ } ) ;
580+
563581 response . pipe ( fileStream ) ;
564582
565583 fileStream . on ( 'finish' , async ( ) => {
@@ -608,9 +626,9 @@ export class MongoBinaryDownload {
608626 reject ( new DownloadError ( downloadUrl , err . message , code ) ) ;
609627 } ) ;
610628
611- request . setTimeout ( 60000 , ( ) => {
629+ request . setTimeout ( timeout , ( ) => {
612630 request . destroy ( ) ;
613- reject ( new DownloadError ( downloadUrl , ' Request timeout after 60 seconds' , 'ETIMEDOUT' ) ) ;
631+ reject ( new DownloadError ( downloadUrl , ` Request timeout after ${ timeout } ms` , 'ETIMEDOUT' ) ) ;
614632 } ) ;
615633 } ) ;
616634 }
@@ -637,7 +655,7 @@ export class MongoBinaryDownload {
637655 const crReturn = this . binaryOpts . platform === 'win32' ? '\x1b[0G' : '\r' ;
638656 const message = `Downloading MongoDB "${ this . binaryOpts . version } ": ${ percentComplete } % (${ mbComplete } mb / ${ this . dlProgress . totalMb } mb)${ crReturn } ` ;
639657
640- if ( process . stdout . isTTY ) {
658+ if ( this . isTTY ) {
641659 // if TTY overwrite last line over and over until finished and clear line to avoid residual characters
642660 clearLine ( process . stdout , 0 ) ; // this is because "process.stdout.clearLine" does not exist anymore
643661 process . stdout . write ( message ) ;
0 commit comments