You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2018/10/31 17:33:24 UTC

[tinkerpop] 01/01: TINKERPOP-2084 Display remote stacktrace in gremlin console

This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2084
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit a8fba325d7433ca71e2209d7cf89a716ccc3958b
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Wed Oct 31 13:31:28 2018 -0400

    TINKERPOP-2084 Display remote stacktrace in gremlin console
    
    Making the remote stacktrace visible to the user saves a visit to the server to determine what went amiss with failed script when the remote failing message is not enough to debug the problem. Plus, it makes the Gremlin Console in ":remote console" mode behave more like it is in local mode.
---
 CHANGELOG.asciidoc                                 |  1 +
 .../tinkerpop/gremlin/console/Console.groovy       |  8 +++++++-
 .../console/jsr223/DriverRemoteAcceptor.java       |  9 +++++---
 .../gremlin/jsr223/console/RemoteException.java    | 24 ++++++++++++++++++++--
 4 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index ac8cba8..e09eeb0 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -27,6 +27,7 @@ This release also includes changes from <<release-3-2-11, 3.2.11>>.
 
 * Fixed `PersistedOutputRDD` to eager persist RDD by adding `count()` action calls.
 * gremlin-python: the graphson deserializer for g:Set should return a python set
+* Display the remote stack trace in the Gremlin Console when scripts sent to the server fail.
 
 [[release-3-3-4]]
 === TinkerPop 3.3.4 (Release Date: October 15, 2018)
diff --git a/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy b/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
index d45b49a..7e80860 100644
--- a/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
+++ b/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
@@ -32,6 +32,7 @@ import org.apache.tinkerpop.gremlin.groovy.loaders.GremlinLoader
 import org.apache.tinkerpop.gremlin.jsr223.CoreGremlinPlugin
 import org.apache.tinkerpop.gremlin.jsr223.GremlinPlugin
 import org.apache.tinkerpop.gremlin.jsr223.ImportCustomizer
+import org.apache.tinkerpop.gremlin.jsr223.console.RemoteException
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation
 import org.apache.tinkerpop.gremlin.structure.Edge
 import org.apache.tinkerpop.gremlin.structure.T
@@ -316,7 +317,12 @@ class Console {
                     io.err.print(line.trim())
                     io.err.println()
                     if (line.trim().equals("y") || line.trim().equals("Y")) {
-                        e.printStackTrace(io.err)
+                        if (err instanceof RemoteException && err.remoteStackTrace.isPresent()) {
+                            io.err.print(err.remoteStackTrace.get())
+                            io.err.flush()
+                        } else {
+                            e.printStackTrace(io.err)
+                        }
                     }
                 } else {
                     e.printStackTrace(io.err)
diff --git a/gremlin-console/src/main/java/org/apache/tinkerpop/gremlin/console/jsr223/DriverRemoteAcceptor.java b/gremlin-console/src/main/java/org/apache/tinkerpop/gremlin/console/jsr223/DriverRemoteAcceptor.java
index 100009d..138b522 100644
--- a/gremlin-console/src/main/java/org/apache/tinkerpop/gremlin/console/jsr223/DriverRemoteAcceptor.java
+++ b/gremlin-console/src/main/java/org/apache/tinkerpop/gremlin/console/jsr223/DriverRemoteAcceptor.java
@@ -173,17 +173,20 @@ public class DriverRemoteAcceptor implements RemoteAcceptor {
             if (inner.isPresent()) {
                 final ResponseException responseException = inner.get();
                 if (responseException.getResponseStatusCode() == ResponseStatusCode.SERVER_ERROR_SERIALIZATION)
-                    throw new RemoteException(String.format("Server could not serialize the result requested. Server error - %s. Note that the class must be serializable by the client and server for proper operation.", responseException.getMessage()));
+                    throw new RemoteException(String.format(
+                            "Server could not serialize the result requested. Server error - %s. Note that the class must be serializable by the client and server for proper operation.", responseException.getMessage()),
+                            responseException.getRemoteStackTrace().orElse(null));
                 else
-                    throw new RemoteException(responseException.getMessage());
+                    throw new RemoteException(responseException.getMessage(), responseException.getRemoteStackTrace().orElse(null));
             } else if (ex.getCause() != null) {
                 final Throwable rootCause = ExceptionUtils.getRootCause(ex);
                 if (rootCause instanceof TimeoutException)
                     throw new RemoteException("Host did not respond in a timely fashion - check the server status and submit again.");
                 else
                     throw new RemoteException(rootCause.getMessage());
-            } else
+            } else {
                 throw new RemoteException(ex.getMessage());
+            }
         }
     }
 
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/console/RemoteException.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/console/RemoteException.java
index 7f4850b..4c59834 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/console/RemoteException.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/console/RemoteException.java
@@ -18,23 +18,43 @@
  */
 package org.apache.tinkerpop.gremlin.jsr223.console;
 
+import java.util.Optional;
+
 /**
  * A mapper {@code Exception} to be thrown when there are problems with processing a command given to a
- * {@link RemoteAcceptor}.  The message provided to the exception will
- * be displayed to the user in the Console.
+ * {@link RemoteAcceptor}.  The message provided to the exception will be displayed to the user in the Console.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class RemoteException extends Exception {
+    private String remoteStackTrace = null;
+
     public RemoteException(final String message) {
+        this(message, (String) null);
+    }
+
+    public RemoteException(final String message, final String remoteStackTrace) {
         super(message);
+        this.remoteStackTrace = remoteStackTrace;
     }
 
     public RemoteException(final String message, final Throwable cause) {
+        this(message, cause, null);
+    }
+
+    public RemoteException(final String message, final Throwable cause, final String remoteStackTrace) {
         super(message, cause);
+        this.remoteStackTrace = remoteStackTrace;
     }
 
     public RemoteException(final Throwable cause) {
         super(cause);
     }
+
+    /**
+     * The stacktrace produced by the remote server.
+     */
+    public Optional<String> getRemoteStackTrace() {
+        return Optional.ofNullable(remoteStackTrace);
+    }
 }