Skip to content

Commit 31b66c6

Browse files
authored
Recover from all panics from non-blocking LSP handlers (microsoft#1306)
1 parent d690e0d commit 31b66c6

File tree

1 file changed

+9
-46
lines changed

1 file changed

+9
-46
lines changed

internal/lsp/server.go

Lines changed: 9 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,15 @@ func (s *Server) dispatchLoop(ctx context.Context) error {
358358
if r := recover(); r != nil {
359359
stack := debug.Stack()
360360
s.Log("panic handling request", req.Method, r, string(stack))
361-
// !!! send something back to client
362-
lspExit()
361+
if isBlockingMethod(req.Method) {
362+
lspExit()
363+
} else {
364+
if req.ID != nil {
365+
s.sendError(req.ID, fmt.Errorf("%w: panic handling request %s: %v", lsproto.ErrInternalError, req.Method, r))
366+
} else {
367+
s.Log("unhandled panic in notification", req.Method, r)
368+
}
369+
}
363370
}
364371
}()
365372
if err := s.handleRequestOrNotification(requestCtx, req); err != nil {
@@ -684,15 +691,6 @@ func (s *Server) handleReferences(ctx context.Context, req *lsproto.RequestMessa
684691
project := s.projectService.EnsureDefaultProjectForURI(params.TextDocument.Uri)
685692
languageService, done := project.GetLanguageServiceForRequest(ctx)
686693
defer done()
687-
// !!! remove this after find all references is fully ported/tested
688-
defer func() {
689-
if r := recover(); r != nil {
690-
stack := debug.Stack()
691-
s.Log("panic obtaining references:", r, string(stack))
692-
s.sendResult(req.ID, []*lsproto.Location{})
693-
}
694-
}()
695-
696694
locations := languageService.ProvideReferences(params)
697695
s.sendResult(req.ID, locations)
698696
return nil
@@ -703,14 +701,6 @@ func (s *Server) handleCompletion(ctx context.Context, req *lsproto.RequestMessa
703701
project := s.projectService.EnsureDefaultProjectForURI(params.TextDocument.Uri)
704702
languageService, done := project.GetLanguageServiceForRequest(ctx)
705703
defer done()
706-
// !!! remove this after completions is fully ported/tested
707-
defer func() {
708-
if r := recover(); r != nil {
709-
stack := debug.Stack()
710-
s.Log("panic obtaining completions:", r, string(stack))
711-
s.sendResult(req.ID, &lsproto.CompletionList{})
712-
}
713-
}()
714704
// !!! get user preferences
715705
list, err := languageService.ProvideCompletion(
716706
ctx,
@@ -731,15 +721,6 @@ func (s *Server) handleDocumentFormat(ctx context.Context, req *lsproto.RequestM
731721
project := s.projectService.EnsureDefaultProjectForURI(params.TextDocument.Uri)
732722
languageService, done := project.GetLanguageServiceForRequest(ctx)
733723
defer done()
734-
// !!! remove this after formatting is fully ported/tested
735-
defer func() {
736-
if r := recover(); r != nil {
737-
stack := debug.Stack()
738-
s.Log("panic on document format:", r, string(stack))
739-
s.sendResult(req.ID, []*lsproto.TextEdit{})
740-
}
741-
}()
742-
743724
res, err := languageService.ProvideFormatDocument(
744725
ctx,
745726
params.TextDocument.Uri,
@@ -757,15 +738,6 @@ func (s *Server) handleDocumentRangeFormat(ctx context.Context, req *lsproto.Req
757738
project := s.projectService.EnsureDefaultProjectForURI(params.TextDocument.Uri)
758739
languageService, done := project.GetLanguageServiceForRequest(ctx)
759740
defer done()
760-
// !!! remove this after formatting is fully ported/tested
761-
defer func() {
762-
if r := recover(); r != nil {
763-
stack := debug.Stack()
764-
s.Log("panic on document range format:", r, string(stack))
765-
s.sendResult(req.ID, []*lsproto.TextEdit{})
766-
}
767-
}()
768-
769741
res, err := languageService.ProvideFormatDocumentRange(
770742
ctx,
771743
params.TextDocument.Uri,
@@ -784,15 +756,6 @@ func (s *Server) handleDocumentOnTypeFormat(ctx context.Context, req *lsproto.Re
784756
project := s.projectService.EnsureDefaultProjectForURI(params.TextDocument.Uri)
785757
languageService, done := project.GetLanguageServiceForRequest(ctx)
786758
defer done()
787-
// !!! remove this after formatting is fully ported/tested
788-
defer func() {
789-
if r := recover(); r != nil {
790-
stack := debug.Stack()
791-
s.Log("panic on type format:", r, string(stack))
792-
s.sendResult(req.ID, []*lsproto.TextEdit{})
793-
}
794-
}()
795-
796759
res, err := languageService.ProvideFormatDocumentOnType(
797760
ctx,
798761
params.TextDocument.Uri,

0 commit comments

Comments
 (0)