[NO ISSUE][*DB][API] Emit exception text on diag eval error

Failure to evaluate diagnostic info generates log & emits exception
string as value, instead of generating 500 & displaying no diag info

Change-Id: Ib4997c57ec3aca4b17c975098865486a6cd72531
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2061
Reviewed-by: Till Westmann <tillw@apache.org>
Tested-by: Michael Blow <mblow@apache.org>
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/DiagnosticsApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/DiagnosticsApiServlet.java
index 3fe591f..eafda09 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/DiagnosticsApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/DiagnosticsApiServlet.java
@@ -45,6 +45,7 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.fasterxml.jackson.databind.node.TextNode;
+
 import io.netty.handler.codec.http.HttpResponseStatus;
 
 public class DiagnosticsApiServlet extends NodeControllerDetailsApiServlet {
@@ -106,9 +107,8 @@
         ncData = new HashMap<>();
         ncData.put("threaddump",
                 executor.submit(() -> fixupKeys((ObjectNode) OBJECT_MAPPER.readTree(hcc.getThreadDump(nc)))));
-        ncData.put("config",
-                executor.submit(
-                        () -> fixupKeys((ObjectNode) OBJECT_MAPPER.readTree(hcc.getNodeDetailsJSON(nc, false, true)))));
+        ncData.put("config", executor
+                .submit(() -> fixupKeys((ObjectNode) OBJECT_MAPPER.readTree(hcc.getNodeDetailsJSON(nc, false, true)))));
         ncData.put("stats", executor.submit(() -> fixupKeys(processNodeStats(hcc, nc))));
         return ncData;
     }
@@ -118,21 +118,29 @@
         ccFutureData = new HashMap<>();
         ccFutureData.put("threaddump",
                 executor.submit(() -> fixupKeys((ObjectNode) OBJECT_MAPPER.readTree(hcc.getThreadDump(null)))));
-        ccFutureData.put("config",
-                executor.submit(() -> fixupKeys(
-                        (ObjectNode) OBJECT_MAPPER.readTree(hcc.getNodeDetailsJSON(null, false, true)))));
-        ccFutureData.put("stats",
-                executor.submit(() -> fixupKeys(
-                        (ObjectNode) OBJECT_MAPPER.readTree(hcc.getNodeDetailsJSON(null, true, false)))));
+        ccFutureData.put("config", executor.submit(
+                () -> fixupKeys((ObjectNode) OBJECT_MAPPER.readTree(hcc.getNodeDetailsJSON(null, false, true)))));
+        ccFutureData.put("stats", executor.submit(
+                () -> fixupKeys((ObjectNode) OBJECT_MAPPER.readTree(hcc.getNodeDetailsJSON(null, true, false)))));
         return ccFutureData;
     }
 
     protected Map<String, JsonNode> resolveFutures(Map<String, Future<JsonNode>> futureMap)
-            throws ExecutionException, InterruptedException {
+            throws InterruptedException {
         Map<String, JsonNode> result = new HashMap<>();
-        for (Map.Entry<String, Future<JsonNode>> entry : futureMap.entrySet()) {
-            result.put(entry.getKey(), entry.getValue().get());
-        }
+        resolveFutures(futureMap, result, result);
         return result;
     }
+
+    protected void resolveFutures(Map<String, Future<JsonNode>> futureMap, Map<String, JsonNode> outputMap,
+            Map<String, JsonNode> errorMap) throws InterruptedException {
+        for (Map.Entry<String, Future<JsonNode>> entry : futureMap.entrySet()) {
+            try {
+                outputMap.put(entry.getKey(), entry.getValue().get());
+            } catch (ExecutionException e) {
+                LOGGER.log(Level.WARNING, "unexpected exception obtaining value for " + entry.getKey(), e);
+                errorMap.put(entry.getKey(), new TextNode(String.valueOf(e)));
+            }
+        }
+    }
 }