@@ -590,63 +590,67 @@ export class RoslynLanguageServer {
590590 const result : string = isString ( data ) ? data : data . toString ( RoslynLanguageServer . encoding ) ;
591591 _channel . append ( '[stderr] ' + result ) ;
592592 } ) ;
593+ childProcess . on ( 'exit' , ( code ) => {
594+ _channel . appendLine ( `Language server process exited with ${ code } ` ) ;
595+ } ) ;
593596
594597 // Timeout promise used to time out the connection process if it takes too long.
595- const timeout = new Promise < undefined > ( ( resolve , reject ) => {
598+ const timeout = new Promise < undefined > ( ( resolve ) => {
596599 RAL ( ) . timer . setTimeout ( resolve , languageServerOptions . startTimeout ) ;
600+ } ) ;
597601
602+ const connectionPromise = new Promise < net . Socket > ( ( resolveConnection , rejectConnection ) => {
598603 // If the child process exited unexpectedly, reject the promise early.
599604 // Error information will be captured from the stdout/stderr streams above.
600605 childProcess . on ( 'exit' , ( code ) => {
601606 if ( code && code !== 0 ) {
602- const message = `Language server process exited with ${ code } ` ;
603- _channel . appendLine ( message ) ;
604- reject ( new Error ( message ) ) ;
607+ rejectConnection ( new Error ( 'Language server process exited unexpectedly' ) ) ;
605608 }
606609 } ) ;
607- } ) ;
608610
609- // The server process will create the named pipe used for communication. Wait for it to be created,
610- // and listen for the server to pass back the connection information via stdout.
611- const namedPipeConnectionPromise = new Promise < NamedPipeInformation > ( ( resolve ) => {
612- _channel . appendLine ( 'waiting for named pipe information from server...' ) ;
613- childProcess . stdout . on ( 'data' , ( data : { toString : ( arg0 : any ) => any } ) => {
614- const result : string = isString ( data ) ? data : data . toString ( RoslynLanguageServer . encoding ) ;
615- // Use the regular expression to find all JSON lines
616- const jsonLines = result . match ( RoslynLanguageServer . namedPipeKeyRegex ) ;
617- if ( jsonLines ) {
618- const transmittedPipeNameInfo : NamedPipeInformation = JSON . parse ( jsonLines [ 0 ] ) ;
619- _channel . appendLine ( 'received named pipe information from server' ) ;
620- resolve ( transmittedPipeNameInfo ) ;
621- }
611+ // The server process will create the named pipe used for communication. Wait for it to be created,
612+ // and listen for the server to pass back the connection information via stdout.
613+ const namedPipePromise = new Promise < NamedPipeInformation > ( ( resolve ) => {
614+ _channel . appendLine ( 'waiting for named pipe information from server...' ) ;
615+ childProcess . stdout . on ( 'data' , ( data : { toString : ( arg0 : any ) => any } ) => {
616+ const result : string = isString ( data ) ? data : data . toString ( RoslynLanguageServer . encoding ) ;
617+ // Use the regular expression to find all JSON lines
618+ const jsonLines = result . match ( RoslynLanguageServer . namedPipeKeyRegex ) ;
619+ if ( jsonLines ) {
620+ const transmittedPipeNameInfo : NamedPipeInformation = JSON . parse ( jsonLines [ 0 ] ) ;
621+ _channel . appendLine ( 'received named pipe information from server' ) ;
622+ resolve ( transmittedPipeNameInfo ) ;
623+ }
624+ } ) ;
622625 } ) ;
623- } ) ;
624626
625- // Wait for the server to send back the name of the pipe to connect to.
626- // If it takes too long it will timeout and throw an error.
627- const pipeConnectionInfo = await Promise . race ( [ namedPipeConnectionPromise , timeout ] ) ;
628- if ( pipeConnectionInfo === undefined ) {
629- throw new Error ( 'Timeout. Named pipe information not received from server.' ) ;
630- }
627+ const socketPromise = namedPipePromise . then ( async ( pipeConnectionInfo ) => {
628+ return new Promise < net . Socket > ( ( resolve , reject ) => {
629+ _channel . appendLine ( 'attempting to connect client to server...' ) ;
630+ const socket = net . createConnection ( pipeConnectionInfo . pipeName , ( ) => {
631+ _channel . appendLine ( 'client has connected to server' ) ;
632+ resolve ( socket ) ;
633+ } ) ;
631634
632- const socketPromise = new Promise < net . Socket > ( ( resolve , reject ) => {
633- _channel . appendLine ( 'attempting to connect client to server...' ) ;
634- const socket = net . createConnection ( pipeConnectionInfo . pipeName , ( ) => {
635- _channel . appendLine ( 'client has connected to server' ) ;
636- resolve ( socket ) ;
635+ // If we failed to connect for any reason, ensure the error is propagated.
636+ socket . on ( 'error' , ( err ) => reject ( err ) ) ;
637+ } ) ;
637638 } ) ;
638639
639- // If we failed to connect for any reason, ensure the error is propagated.
640- socket . on ( 'error' , ( err ) => reject ( err ) ) ;
640+ socketPromise . then ( resolveConnection , rejectConnection ) ;
641641 } ) ;
642642
643643 // Wait for the client to connect to the named pipe.
644- // If it takes too long it will timeout and throw an error.
645- const socket = await Promise . race ( [ socketPromise , timeout ] ) ;
644+ let socket : net . Socket | undefined ;
645+ if ( commonOptions . waitForDebugger ) {
646+ // Do not timeout the connection when the waitForDebugger option is set.
647+ socket = await connectionPromise ;
648+ } else {
649+ socket = await Promise . race ( [ connectionPromise , timeout ] ) ;
650+ }
651+
646652 if ( socket === undefined ) {
647- throw new Error (
648- 'Timeout. Client cound not connect to server via named pipe: ' + pipeConnectionInfo . pipeName
649- ) ;
653+ throw new Error ( 'Timeout. Client cound not connect to server via named pipe' ) ;
650654 }
651655
652656 return {
0 commit comments