Skip to content

Commit f89a64d

Browse files
authored
Fix panic recovery in server and fail test updater on unrecovered panics (#1644)
1 parent 52f2ee4 commit f89a64d

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

internal/fourslash/_scripts/updateFailing.mts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { main as convertFourslash } from "./convertFourslash.mts";
77
const failingTestsPath = path.join(import.meta.dirname, "failingTests.txt");
88

99
function main() {
10+
const oldFailingTests = fs.readFileSync(failingTestsPath, "utf-8");
1011
fs.writeFileSync(failingTestsPath, "", "utf-8");
1112
convertFourslash();
1213
const go = which.sync("go");
@@ -17,11 +18,16 @@ function main() {
1718
catch (error) {
1819
testOutput = (error as { stdout: string; }).stdout as string;
1920
}
20-
const regex = /--- FAIL: ([\S]+)/gm;
21+
const panicRegex = /^panic/m;
22+
if (panicRegex.test(testOutput)) {
23+
fs.writeFileSync(failingTestsPath, oldFailingTests, "utf-8");
24+
throw new Error("Unrecovered panic detected in tests");
25+
}
26+
const failRegex = /--- FAIL: ([\S]+)/gm;
2127
const failingTests: string[] = [];
2228
let match;
2329

24-
while ((match = regex.exec(testOutput)) !== null) {
30+
while ((match = failRegex.exec(testOutput)) !== null) {
2531
failingTests.push(match[1]);
2632
}
2733

internal/lsp/server.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ func (s *Server) readLoop(ctx context.Context) error {
260260
if s.initializeParams == nil && msg.Kind == lsproto.MessageKindRequest {
261261
req := msg.AsRequest()
262262
if req.Method == lsproto.MethodInitialize {
263-
resp, err := s.handleInitialize(ctx, req.Params.(*lsproto.InitializeParams), func() {})
263+
resp, err := s.handleInitialize(ctx, req.Params.(*lsproto.InitializeParams), req)
264264
if err != nil {
265265
return err
266266
}
@@ -480,16 +480,18 @@ func registerNotificationHandler[Req any](handlers handlerMap, info lsproto.Noti
480480
}
481481
}
482482

483-
func registerRequestHandler[Req, Resp any](handlers handlerMap, info lsproto.RequestInfo[Req, Resp], fn func(*Server, context.Context, Req, func()) (Resp, error)) {
483+
func registerRequestHandler[Req, Resp any](
484+
handlers handlerMap,
485+
info lsproto.RequestInfo[Req, Resp],
486+
fn func(*Server, context.Context, Req, *lsproto.RequestMessage) (Resp, error),
487+
) {
484488
handlers[info.Method] = func(s *Server, ctx context.Context, req *lsproto.RequestMessage) error {
485489
var params Req
486490
// Ignore empty params.
487491
if req.Params != nil {
488492
params = req.Params.(Req)
489493
}
490-
resp, err := fn(s, ctx, params, func() {
491-
s.recover(req)
492-
})
494+
resp, err := fn(s, ctx, params, req)
493495
if err != nil {
494496
return err
495497
}
@@ -537,7 +539,7 @@ func (s *Server) recover(req *lsproto.RequestMessage) {
537539
}
538540
}
539541

540-
func (s *Server) handleInitialize(ctx context.Context, params *lsproto.InitializeParams, _ func()) (lsproto.InitializeResponse, error) {
542+
func (s *Server) handleInitialize(ctx context.Context, params *lsproto.InitializeParams, _ *lsproto.RequestMessage) (lsproto.InitializeResponse, error) {
541543
if s.initializeParams != nil {
542544
return nil, lsproto.ErrInvalidRequest
543545
}
@@ -661,7 +663,7 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali
661663
return nil
662664
}
663665

664-
func (s *Server) handleShutdown(ctx context.Context, params any, _ func()) (lsproto.ShutdownResponse, error) {
666+
func (s *Server) handleShutdown(ctx context.Context, params any, _ *lsproto.RequestMessage) (lsproto.ShutdownResponse, error) {
665667
s.session.Close()
666668
return lsproto.ShutdownResponse{}, nil
667669
}
@@ -758,7 +760,7 @@ func (s *Server) handleCompletion(ctx context.Context, languageService *ls.Langu
758760
&ls.UserPreferences{})
759761
}
760762

761-
func (s *Server) handleCompletionItemResolve(ctx context.Context, params *lsproto.CompletionItem, recoverAndSendError func()) (lsproto.CompletionResolveResponse, error) {
763+
func (s *Server) handleCompletionItemResolve(ctx context.Context, params *lsproto.CompletionItem, reqMsg *lsproto.RequestMessage) (lsproto.CompletionResolveResponse, error) {
762764
data, err := ls.GetCompletionItemData(params)
763765
if err != nil {
764766
return nil, err
@@ -767,7 +769,7 @@ func (s *Server) handleCompletionItemResolve(ctx context.Context, params *lsprot
767769
if err != nil {
768770
return nil, err
769771
}
770-
defer recoverAndSendError()
772+
defer s.recover(reqMsg)
771773
return languageService.ResolveCompletionItem(
772774
ctx,
773775
params,
@@ -804,10 +806,10 @@ func (s *Server) handleDocumentOnTypeFormat(ctx context.Context, ls *ls.Language
804806
)
805807
}
806808

807-
func (s *Server) handleWorkspaceSymbol(ctx context.Context, params *lsproto.WorkspaceSymbolParams, recoverAndSendError func()) (lsproto.WorkspaceSymbolResponse, error) {
809+
func (s *Server) handleWorkspaceSymbol(ctx context.Context, params *lsproto.WorkspaceSymbolParams, reqMsg *lsproto.RequestMessage) (lsproto.WorkspaceSymbolResponse, error) {
808810
snapshot, release := s.session.Snapshot()
809811
defer release()
810-
defer recoverAndSendError()
812+
defer s.recover(reqMsg)
811813
programs := core.Map(snapshot.ProjectCollection.Projects(), (*project.Project).GetProgram)
812814
return ls.ProvideWorkspaceSymbols(ctx, programs, snapshot.Converters(), params.Query)
813815
}

0 commit comments

Comments
 (0)