@@ -142,11 +142,15 @@ export class LSPClient {
142142 this . markTransportClosed ( ) ;
143143 } ) ;
144144
145- // 子进程退出后,stdin 可能先于上层状态同步被销毁;这里要吞掉 error 事件,
146- // 并把连接状态标记为关闭,避免后续继续写入触发未捕获异常导致 CLI 闪退。
147145 this . process . stdin ?. on ( 'error' , ( ) => {
148146 this . markTransportClosed ( ) ;
149147 } ) ;
148+ this . process . stdout ?. on ( 'error' , ( ) => {
149+ this . markTransportClosed ( ) ;
150+ } ) ;
151+ this . process . stderr ?. on ( 'error' , ( ) => {
152+ this . markTransportClosed ( ) ;
153+ } ) ;
150154
151155 processManager . register ( this . process ) ;
152156
@@ -155,10 +159,20 @@ export class LSPClient {
155159 new StreamMessageWriter ( this . process . stdin ! ) ,
156160 ) ;
157161
158- // Handle connection-level errors and closure
162+ // Handle connection-level errors and closure.
163+ // Suppress stream-destroyed errors that occur when the child process exits
164+ // while a write is still in-flight – these are expected during teardown.
159165 this . connection . onError ( ( [ error ] ) => {
160166 this . markTransportClosed ( ) ;
161- console . debug ( 'LSP connection error:' , error ?. message || error ) ;
167+ const msg = error ?. message || '' ;
168+ if (
169+ msg . includes ( 'stream was destroyed' ) ||
170+ msg . includes ( 'ERR_STREAM_DESTROYED' ) ||
171+ msg . includes ( 'write after end' )
172+ ) {
173+ return ;
174+ }
175+ console . debug ( 'LSP connection error:' , msg || error ) ;
162176 } ) ;
163177 this . connection . onClose ( ( ) => {
164178 this . markTransportClosed ( ) ;
@@ -381,8 +395,8 @@ export class LSPClient {
381395 }
382396
383397 async gotoDefinition ( uri : string , position : Position ) : Promise < Location [ ] > {
384- if ( ! this . connection || ! this . isInitialized ) {
385- throw new Error ( 'LSP client not initialized' ) ;
398+ if ( ! this . canSendMessages ( ) ) {
399+ return [ ] ;
386400 }
387401
388402 if ( this . config . language === 'csharp' && this . csharpSolutionLoadPromise ) {
@@ -402,7 +416,7 @@ export class LSPClient {
402416 } ;
403417
404418 try {
405- const result = await this . connection . sendRequest <
419+ const result = await this . connection ! . sendRequest <
406420 Location | Location [ ] | null
407421 > ( 'textDocument/definition' , params ) ;
408422
@@ -412,7 +426,7 @@ export class LSPClient {
412426
413427 return Array . isArray ( result ) ? result : [ result ] ;
414428 } catch ( error ) {
415- console . debug ( 'LSP gotoDefinition error:' , error ) ;
429+ this . markTransportClosed ( ) ;
416430 return [ ] ;
417431 }
418432 }
@@ -422,8 +436,8 @@ export class LSPClient {
422436 position : Position ,
423437 includeDeclaration = false ,
424438 ) : Promise < Location [ ] > {
425- if ( ! this . connection || ! this . isInitialized ) {
426- throw new Error ( 'LSP client not initialized' ) ;
439+ if ( ! this . canSendMessages ( ) ) {
440+ return [ ] ;
427441 }
428442
429443 if ( ! this . capabilities ?. referencesProvider ) {
@@ -437,21 +451,21 @@ export class LSPClient {
437451 } ;
438452
439453 try {
440- const result = await this . connection . sendRequest < Location [ ] | null > (
454+ const result = await this . connection ! . sendRequest < Location [ ] | null > (
441455 'textDocument/references' ,
442456 params ,
443457 ) ;
444458
445459 return result || [ ] ;
446460 } catch ( error ) {
447- console . debug ( 'LSP findReferences failed:' , error ) ;
461+ this . markTransportClosed ( ) ;
448462 return [ ] ;
449463 }
450464 }
451465
452466 async hover ( uri : string , position : Position ) : Promise < Hover | null > {
453- if ( ! this . connection || ! this . isInitialized ) {
454- throw new Error ( 'LSP client not initialized' ) ;
467+ if ( ! this . canSendMessages ( ) ) {
468+ return null ;
455469 }
456470
457471 if ( ! this . capabilities ?. hoverProvider ) {
@@ -464,21 +478,21 @@ export class LSPClient {
464478 } ;
465479
466480 try {
467- const result = await this . connection . sendRequest < Hover | null > (
481+ const result = await this . connection ! . sendRequest < Hover | null > (
468482 'textDocument/hover' ,
469483 params ,
470484 ) ;
471485
472486 return result ;
473487 } catch ( error ) {
474- console . debug ( 'LSP hover failed:' , error ) ;
488+ this . markTransportClosed ( ) ;
475489 return null ;
476490 }
477491 }
478492
479493 async completion ( uri : string , position : Position ) : Promise < CompletionItem [ ] > {
480- if ( ! this . connection || ! this . isInitialized ) {
481- throw new Error ( 'LSP client not initialized' ) ;
494+ if ( ! this . canSendMessages ( ) ) {
495+ return [ ] ;
482496 }
483497
484498 if ( ! this . capabilities ?. completionProvider ) {
@@ -491,7 +505,7 @@ export class LSPClient {
491505 } ;
492506
493507 try {
494- const result = await this . connection . sendRequest <
508+ const result = await this . connection ! . sendRequest <
495509 CompletionItem [ ] | { items : CompletionItem [ ] } | null
496510 > ( 'textDocument/completion' , params ) ;
497511
@@ -501,16 +515,16 @@ export class LSPClient {
501515
502516 return Array . isArray ( result ) ? result : result . items || [ ] ;
503517 } catch ( error ) {
504- console . debug ( 'LSP completion failed:' , error ) ;
518+ this . markTransportClosed ( ) ;
505519 return [ ] ;
506520 }
507521 }
508522
509523 async documentSymbol (
510524 uri : string ,
511525 ) : Promise < DocumentSymbol [ ] | SymbolInformation [ ] > {
512- if ( ! this . connection || ! this . isInitialized ) {
513- throw new Error ( 'LSP client not initialized' ) ;
526+ if ( ! this . canSendMessages ( ) ) {
527+ return [ ] ;
514528 }
515529
516530 if ( ! this . capabilities ?. documentSymbolProvider ) {
@@ -522,13 +536,13 @@ export class LSPClient {
522536 } ;
523537
524538 try {
525- const result = await this . connection . sendRequest <
539+ const result = await this . connection ! . sendRequest <
526540 DocumentSymbol [ ] | SymbolInformation [ ] | null
527541 > ( 'textDocument/documentSymbol' , params ) ;
528542
529543 return result || [ ] ;
530544 } catch ( error ) {
531- console . debug ( 'LSP documentSymbol failed:' , error ) ;
545+ this . markTransportClosed ( ) ;
532546 return [ ] ;
533547 }
534548 }
0 commit comments