]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/jsonrpc/JsonRpcReader.java
Show better error message when receiving an empty JSON RPC line
[signal-cli] / src / main / java / org / asamk / signal / jsonrpc / JsonRpcReader.java
index 16f5fbd0f85a9c085d42bf5025acb0a716dda4ea..327342a205a22be4299308513d90538156a63583 100644 (file)
@@ -23,7 +23,7 @@ import java.util.stream.StreamSupport;
 
 public class JsonRpcReader {
 
-    private final static Logger logger = LoggerFactory.getLogger(JsonRpcReader.class);
+    private static final Logger logger = LoggerFactory.getLogger(JsonRpcReader.class);
 
     private final JsonRpcSender jsonRpcSender;
     private final ObjectMapper objectMapper;
@@ -55,8 +55,7 @@ public class JsonRpcReader {
             return;
         }
 
-        final var executor = Executors.newFixedThreadPool(10);
-        try {
+        try (final var executor = Executors.newCachedThreadPool()) {
             while (!Thread.interrupted()) {
                 final var input = lineSupplier.get();
                 if (input == null) {
@@ -72,8 +71,6 @@ public class JsonRpcReader {
 
                 executor.submit(() -> handleMessage(message, requestHandler, responseHandler));
             }
-        } finally {
-            Util.closeExecutorService(executor);
         }
     }
 
@@ -82,53 +79,52 @@ public class JsonRpcReader {
             final RequestHandler requestHandler,
             final Consumer<JsonRpcResponse> responseHandler
     ) {
-        if (message instanceof final JsonRpcRequest jsonRpcRequest) {
-            logger.debug("Received json rpc request, method: " + jsonRpcRequest.getMethod());
-            final var response = handleRequest(requestHandler, jsonRpcRequest);
-            if (response != null) {
-                jsonRpcSender.sendResponse(response);
+        switch (message) {
+            case JsonRpcRequest jsonRpcRequest -> {
+                logger.debug("Received json rpc request, method: " + jsonRpcRequest.getMethod());
+                final var response = handleRequest(requestHandler, jsonRpcRequest);
+                if (response != null) {
+                    jsonRpcSender.sendResponse(response);
+                }
             }
-        } else if (message instanceof JsonRpcResponse jsonRpcResponse) {
-            responseHandler.accept(jsonRpcResponse);
-        } else {
-            final var messages = ((JsonRpcBatchMessage) message).getMessages();
-            final var responseList = new ArrayList<JsonRpcResponse>(messages.size());
-            final var executor = Executors.newFixedThreadPool(10);
-            try {
-                final var lock = new ReentrantLock();
-                messages.forEach(jsonNode -> {
-                    final JsonRpcRequest request;
-                    try {
-                        request = parseJsonRpcRequest(jsonNode);
-                    } catch (JsonRpcException e) {
-                        final var response = JsonRpcResponse.forError(e.getError(), getId(jsonNode));
-                        lock.lock();
+            case JsonRpcResponse jsonRpcResponse -> responseHandler.accept(jsonRpcResponse);
+            case JsonRpcBatchMessage jsonRpcBatchMessage -> {
+                final var messages = jsonRpcBatchMessage.getMessages();
+                final var responseList = new ArrayList<JsonRpcResponse>(messages.size());
+                try (final var executor = Executors.newCachedThreadPool()) {
+                    final var lock = new ReentrantLock();
+                    messages.forEach(jsonNode -> {
+                        final JsonRpcRequest request;
                         try {
-                            responseList.add(response);
-                        } finally {
-                            lock.unlock();
-                        }
-                        return;
-                    }
-
-                    executor.submit(() -> {
-                        final var response = handleRequest(requestHandler, request);
-                        if (response != null) {
+                            request = parseJsonRpcRequest(jsonNode);
+                        } catch (JsonRpcException e) {
+                            final var response = JsonRpcResponse.forError(e.getError(), getId(jsonNode));
                             lock.lock();
                             try {
                                 responseList.add(response);
                             } finally {
                                 lock.unlock();
                             }
+                            return;
                         }
+
+                        executor.submit(() -> {
+                            final var response = handleRequest(requestHandler, request);
+                            if (response != null) {
+                                lock.lock();
+                                try {
+                                    responseList.add(response);
+                                } finally {
+                                    lock.unlock();
+                                }
+                            }
+                        });
                     });
-                });
-            } finally {
-                Util.closeExecutorService(executor);
-            }
+                }
 
-            if (responseList.size() > 0) {
-                jsonRpcSender.sendBatchResponses(responseList);
+                if (!responseList.isEmpty()) {
+                    jsonRpcSender.sendBatchResponses(responseList);
+                }
             }
         }
     }
@@ -155,6 +151,13 @@ public class JsonRpcReader {
     }
 
     private JsonRpcMessage parseJsonRpcMessage(final String input) {
+        if (input.trim().isEmpty()) {
+            jsonRpcSender.sendResponse(JsonRpcResponse.forError(new JsonRpcResponse.Error(JsonRpcResponse.Error.PARSE_ERROR,
+                    "Empty input line",
+                    null), null));
+            return null;
+        }
+
         final JsonNode jsonNode;
         try {
             jsonNode = objectMapper.readTree(input);
@@ -193,7 +196,7 @@ public class JsonRpcReader {
                     null), null));
             return null;
         } else if (jsonNode.isArray()) {
-            if (jsonNode.size() == 0) {
+            if (jsonNode.isEmpty()) {
                 jsonRpcSender.sendResponse(JsonRpcResponse.forError(new JsonRpcResponse.Error(JsonRpcResponse.Error.INVALID_REQUEST,
                         "invalid request",
                         null), null));
@@ -221,7 +224,7 @@ public class JsonRpcReader {
 
     private ValueNode getId(JsonNode jsonNode) {
         final var id = jsonNode.get("id");
-        return id instanceof ValueNode ? (ValueNode) id : null;
+        return id instanceof ValueNode value ? value : null;
     }
 
     private JsonRpcRequest parseJsonRpcRequest(final JsonNode input) throws JsonRpcException {