diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java index df866c4ccd71..113483625290 100644 --- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java +++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java @@ -78,6 +78,7 @@ import org.eclipse.lsp4j.jsonrpc.Launcher; import org.eclipse.lsp4j.jsonrpc.MessageConsumer; import org.eclipse.lsp4j.jsonrpc.MessageIssueException; +import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.jsonrpc.messages.Message; import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage; @@ -119,6 +120,7 @@ import org.netbeans.spi.project.ActionProvider; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.NbPreferences; @@ -180,6 +182,11 @@ private static Launcher createLauncher(LanguageServerImpl } }); }) + .setExceptionHandler((t) -> { + System.err.println("Error during dispatch at server "); + t.printStackTrace(); + return RemoteEndpoint.DEFAULT_EXCEPTION_HANDLER.apply(t); + }) .create(); } @@ -255,6 +262,16 @@ public void consume(Message msg) throws MessageIssueException, JsonRpcException Lookups.executeWith(ll, () -> { try { delegate.consume(msg); + } catch (RuntimeException | Error e) { + System.err.println("Error occurred during message dispatch"); + e.printStackTrace(); + LOG.log(Level.WARNING, "Error occurred during message dispatch", e); + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } + throw e; } finally { // cancel while the OperationContext is still active. if (ftoCancel != null) { diff --git a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java index 367718191951..ac23790a6212 100644 --- a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java +++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java @@ -25,7 +25,10 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.io.PrintWriter; import java.io.Writer; import java.lang.ref.Reference; import java.lang.ref.WeakReference; @@ -140,8 +143,14 @@ import org.eclipse.lsp4j.WorkspaceSymbol; import org.eclipse.lsp4j.WorkspaceSymbolLocation; import org.eclipse.lsp4j.WorkspaceSymbolParams; +import org.eclipse.lsp4j.jsonrpc.Endpoint; import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.jsonrpc.MessageConsumer; +import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint; +import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler; +import org.eclipse.lsp4j.jsonrpc.json.StreamMessageConsumer; import org.eclipse.lsp4j.jsonrpc.messages.Either; +import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints; import org.eclipse.lsp4j.launch.LSPLauncher; import org.eclipse.lsp4j.services.LanguageClient; import org.eclipse.lsp4j.services.LanguageServer; @@ -1589,14 +1598,14 @@ public void testFixImports() throws Exception { } List[] diags = new List[1]; CountDownLatch indexingComplete = new CountDownLatch(1); - Launcher serverLauncher = LSPLauncher.createClientLauncher(new TestCodeLanguageClient() { + Launcher serverLauncher = createClientLauncherWithLogging(new TestCodeLanguageClient() { @Override public void showStatusBarMessage(ShowStatusMessageParams params) { if (Server.INDEXING_COMPLETED.equals(params.getMessage())) { indexingComplete.countDown(); } } - + @Override public void publishDiagnostics(PublishDiagnosticsParams params) { synchronized (diags) { @@ -3674,7 +3683,7 @@ public void testMoveClass() throws Exception { List[] diags = new List[1]; CountDownLatch indexingComplete = new CountDownLatch(1); WorkspaceEdit[] edit = new WorkspaceEdit[1]; - Launcher serverLauncher = LSPLauncher.createClientLauncher(new TestCodeLanguageClient() { + Launcher serverLauncher = createClientLauncherWithLogging(new TestCodeLanguageClient() { @Override public void publishDiagnostics(PublishDiagnosticsParams params) { synchronized (diags) { @@ -3789,7 +3798,7 @@ public void testMoveMethod() throws Exception { List[] diags = new List[1]; CountDownLatch indexingComplete = new CountDownLatch(1); WorkspaceEdit[] edit = new WorkspaceEdit[1]; - Launcher serverLauncher = LSPLauncher.createClientLauncher(new TestCodeLanguageClient() { + Launcher serverLauncher = createClientLauncherWithLogging(new TestCodeLanguageClient() { @Override public void publishDiagnostics(PublishDiagnosticsParams params) { synchronized (diags) { @@ -4334,6 +4343,20 @@ public CompletableFuture> showQuickPick(ShowQuickPickParams } } } + + private Launcher createClientLauncherWithLogging(LanguageClient client, InputStream input, OutputStream output) { + return new LSPLauncher.Builder() + .setLocalService(client) + .setExceptionHandler((t) -> { + System.err.println("Error during dispatch at client: "); + t.printStackTrace(); + return RemoteEndpoint.DEFAULT_EXCEPTION_HANDLER.apply(t); + }) + .traceMessages(new PrintWriter(System.out)) + .setRemoteInterface(LanguageServer.class) + .setInput(input) + .setOutput(output).create(); + } public void testChangeMethodParameters() throws Exception { File src = new File(getWorkDir(), "a/Foo.java");