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 2017/04/18 20:29:55 UTC
[1/6] tinkerpop git commit: TINKERPOP-1044 Additional error data to
Gremlin Server responses
Repository: tinkerpop
Updated Branches:
refs/heads/master 3d857cb2b -> 00057b9b1
TINKERPOP-1044 Additional error data to Gremlin Server responses
Applies to all protocols: http, nio, and websocket. Added stack trace and exception hierarchy. Deprecated the "Exception-Class" in the http protocol.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/b29bab0a
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/b29bab0a
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/b29bab0a
Branch: refs/heads/master
Commit: b29bab0acada54aa525184935d96b41f9cf0854b
Parents: 95d3efc
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Apr 6 17:55:39 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Apr 6 17:55:39 2017 -0400
----------------------------------------------------------------------
.../tinkerpop/gremlin/driver/Handler.java | 11 ++++--
.../apache/tinkerpop/gremlin/driver/Tokens.java | 3 ++
.../driver/exception/ResponseException.java | 20 +++++++++++
.../gremlin/driver/message/ResponseMessage.java | 19 ++++++++++
.../gremlin/driver/ResultQueueTest.java | 2 --
.../handler/GremlinResponseFrameEncoder.java | 6 ++--
.../handler/HttpGremlinEndpointHandler.java | 9 +++--
.../gremlin/server/handler/IteratorHandler.java | 5 ++-
.../handler/NioGremlinResponseEncoder.java | 5 +--
.../server/handler/OpExecutorHandler.java | 1 +
.../server/handler/OpSelectorHandler.java | 4 ++-
.../handler/WsGremlinResponseEncoder.java | 5 +--
.../server/op/AbstractEvalOpProcessor.java | 31 +++++++++++-----
.../gremlin/server/op/AbstractOpProcessor.java | 5 +--
.../op/traversal/TraversalOpProcessor.java | 35 +++++++++++++-----
.../gremlin/server/util/ExceptionHelper.java | 38 ++++++++++++++++++++
.../server/GremlinDriverIntegrateTest.java | 5 +++
.../server/GremlinServerHttpIntegrateTest.java | 8 +++++
18 files changed, 179 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
index 650bc2f..1bd0a3b 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
@@ -235,8 +235,15 @@ final class Handler {
}
} else {
// this is a "success" but represents no results otherwise it is an error
- if (statusCode != ResponseStatusCode.NO_CONTENT)
- queue.markError(new ResponseException(response.getStatus().getCode(), response.getStatus().getMessage()));
+ if (statusCode != ResponseStatusCode.NO_CONTENT) {
+ final Map<String,Object> attributes = response.getStatus().getAttributes();
+ final String stackTrace = attributes.containsKey(Tokens.STATUS_ATTRIBUTE_STACK_TRACE) ?
+ (String) attributes.get(Tokens.STATUS_ATTRIBUTE_STACK_TRACE) : null;
+ final List<String> exceptions = attributes.containsKey(Tokens.STATUS_ATTRIBUTE_EXCEPTIONS) ?
+ (List<String>) attributes.get(Tokens.STATUS_ATTRIBUTE_EXCEPTIONS) : null;
+ queue.markError(new ResponseException(response.getStatus().getCode(), response.getStatus().getMessage(),
+ exceptions, stackTrace));
+ }
}
// as this is a non-PARTIAL_CONTENT code - the stream is done
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Tokens.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Tokens.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Tokens.java
index fb577d7..9aee728 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Tokens.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Tokens.java
@@ -155,4 +155,7 @@ public final class Tokens {
public static final String VAL_AGGREGATE_TO_SET = "set";
public static final String VAL_TRAVERSAL_SOURCE_ALIAS = "g";
+
+ public static final String STATUS_ATTRIBUTE_EXCEPTIONS = "exceptions";
+ public static final String STATUS_ATTRIBUTE_STACK_TRACE = "stackTrace";
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java
index 3ae4e75..800c2fc 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java
@@ -20,18 +20,38 @@ package org.apache.tinkerpop.gremlin.driver.exception;
import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
+import java.util.List;
+import java.util.Optional;
+
/**
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public class ResponseException extends Exception {
private ResponseStatusCode responseStatusCode;
+ private String remoteStackTrace = null;
+ private List<String> remoteExceptionHierarchy = null;
public ResponseException(final ResponseStatusCode responseStatusCode, final String serverMessage) {
super(serverMessage);
this.responseStatusCode = responseStatusCode;
}
+ public ResponseException(final ResponseStatusCode responseStatusCode, final String serverMessage,
+ final List<String> remoteExceptionHierarchy, final String remoteStackTrace) {
+ this(responseStatusCode, serverMessage);
+ this.remoteExceptionHierarchy = remoteExceptionHierarchy;
+ this.remoteStackTrace = remoteStackTrace;
+ }
+
public ResponseStatusCode getResponseStatusCode() {
return responseStatusCode;
}
+
+ public Optional<String> getRemoteStackTrace() {
+ return Optional.ofNullable(remoteStackTrace);
+ }
+
+ public Optional<List<String>> getRemoteExceptionHierarchy() {
+ return Optional.ofNullable(remoteExceptionHierarchy);
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseMessage.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseMessage.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseMessage.java
index c5a00f6..f4126b1 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseMessage.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/ResponseMessage.java
@@ -18,7 +18,12 @@
*/
package org.apache.tinkerpop.gremlin.driver.message;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.tinkerpop.gremlin.driver.Tokens;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@@ -102,6 +107,20 @@ public final class ResponseMessage {
return this;
}
+ public Builder statusAttributeException(final Throwable ex) {
+ statusAttribute(Tokens.STATUS_ATTRIBUTE_EXCEPTIONS, IteratorUtils.asList(
+ IteratorUtils.map(ExceptionUtils.getThrowableList(ex), t -> t.getClass().getName())));
+ statusAttribute(Tokens.STATUS_ATTRIBUTE_STACK_TRACE, ExceptionUtils.getFullStackTrace(ex));
+ return this;
+ }
+
+ public Builder statusAttribute(final String key, final Object value) {
+ if (this.attributes == Collections.EMPTY_MAP)
+ attributes = new HashMap<>();
+ attributes.put(key, value);
+ return this;
+ }
+
public Builder result(final Object result) {
this.result = result;
return this;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultQueueTest.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultQueueTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultQueueTest.java
index 67bbc48..a7e6066 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultQueueTest.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultQueueTest.java
@@ -37,8 +37,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.core.IsCollectionContaining.hasItem;
-import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/GremlinResponseFrameEncoder.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/GremlinResponseFrameEncoder.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/GremlinResponseFrameEncoder.java
index d0f9d76..3aa8c36 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/GremlinResponseFrameEncoder.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/GremlinResponseFrameEncoder.java
@@ -20,11 +20,13 @@ package org.apache.tinkerpop.gremlin.server.handler;
import com.codahale.metrics.Meter;
import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
+import org.apache.tinkerpop.gremlin.driver.Tokens;
import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
import org.apache.tinkerpop.gremlin.driver.ser.MessageTextSerializer;
import org.apache.tinkerpop.gremlin.server.GremlinServer;
import org.apache.tinkerpop.gremlin.server.op.session.Session;
+import org.apache.tinkerpop.gremlin.server.util.ExceptionHelper;
import org.apache.tinkerpop.gremlin.server.util.MetricManager;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
@@ -91,10 +93,10 @@ public class GremlinResponseFrameEncoder extends MessageToMessageEncoder<Respons
} catch (Exception ex) {
errorMeter.mark();
logger.warn("The result [{}] in the request {} could not be serialized and returned.", o.getResult(), o.getRequestId(), ex);
- final String errorMessage = String.format("Error during serialization: %s",
- ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage());
+ final String errorMessage = String.format("Error during serialization: %s", ExceptionHelper.getMessageFromExceptionOrCause(ex));
final ResponseMessage error = ResponseMessage.build(o.getRequestId())
.statusMessage(errorMessage)
+ .statusAttributeException(ex)
.code(ResponseStatusCode.SERVER_ERROR_SERIALIZATION).create();
if (useBinary) {
objects.add(serializer.serializeResponseAsBinary(error, ctx.alloc()));
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
index 899d488..a1030cc 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
@@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.server.handler;
import com.codahale.metrics.Meter;
import com.codahale.metrics.Timer;
+import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
import org.apache.tinkerpop.gremlin.driver.Tokens;
import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
@@ -49,7 +50,6 @@ import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
-import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
import org.apache.tinkerpop.shaded.jackson.databind.node.ArrayNode;
@@ -457,8 +457,13 @@ public class HttpGremlinEndpointHandler extends ChannelInboundHandlerAdapter {
errorMeter.mark();
final ObjectNode node = mapper.createObjectNode();
node.put("message", message);
- if (t.isPresent()){
+ if (t.isPresent()) {
+ // "Exception-Class" needs to go away - didn't realize it was named that way during review for some reason.
+ // replaced with the same method for exception reporting as is used with websocket/nio protocol
node.put("Exception-Class", t.get().getClass().getName());
+ final ArrayNode exceptionList = node.putArray(Tokens.STATUS_ATTRIBUTE_EXCEPTIONS);
+ ExceptionUtils.getThrowableList(t.get()).forEach(throwable -> exceptionList.add(throwable.getClass().getName()));
+ node.put(Tokens.STATUS_ATTRIBUTE_STACK_TRACE, ExceptionUtils.getFullStackTrace(t.get()));
}
final FullHttpResponse response = new DefaultFullHttpResponse(
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java
index 527aa37..78e2dc9 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java
@@ -110,7 +110,10 @@ public class IteratorHandler extends ChannelOutboundHandlerAdapter {
if (!f.isSuccess()) {
final String errorMessage = String.format("Response iteration and serialization exceeded the configured threshold for request [%s] - %s", msg, f.cause().getMessage());
logger.warn(errorMessage);
- ctx.writeAndFlush(ResponseMessage.build(requestMessage).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage(errorMessage).create());
+ ctx.writeAndFlush(ResponseMessage.build(requestMessage)
+ .code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+ .statusAttributeException(f.cause())
+ .statusMessage(errorMessage).create());
}
});
} finally {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java
index 6a98b8b..79368c1 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java
@@ -25,6 +25,7 @@ import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
import org.apache.tinkerpop.gremlin.driver.ser.MessageTextSerializer;
import org.apache.tinkerpop.gremlin.server.GremlinServer;
+import org.apache.tinkerpop.gremlin.server.util.ExceptionHelper;
import org.apache.tinkerpop.gremlin.server.util.MetricManager;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
@@ -72,10 +73,10 @@ public class NioGremlinResponseEncoder extends MessageToByteEncoder<ResponseMess
} catch (Exception ex) {
errorMeter.mark();
logger.warn("The result [{}] in the request {} could not be serialized and returned.", responseMessage.getResult(), responseMessage.getRequestId(), ex);
- final String errorMessage = String.format("Error during serialization: %s",
- ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage());
+ final String errorMessage = String.format("Error during serialization: %s", ExceptionHelper.getMessageFromExceptionOrCause(ex));
final ResponseMessage error = ResponseMessage.build(responseMessage.getRequestId())
.statusMessage(errorMessage)
+ .statusAttributeException(ex)
.code(ResponseStatusCode.SERVER_ERROR_SERIALIZATION).create();
if (useBinary) {
final ByteBuf bytes = serializer.serializeResponseAsBinary(error, ctx.alloc());
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpExecutorHandler.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpExecutorHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpExecutorHandler.java
index eefe600..477cb11 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpExecutorHandler.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpExecutorHandler.java
@@ -77,6 +77,7 @@ public class OpExecutorHandler extends SimpleChannelInboundHandler<Pair<RequestM
logger.warn(ex.getMessage(), ex);
ctx.writeAndFlush(ResponseMessage.build(msg)
.code(ResponseStatusCode.SERVER_ERROR)
+ .statusAttributeException(ex)
.statusMessage(ex.getMessage()).create());
} finally {
ReferenceCountUtil.release(objects);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpSelectorHandler.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpSelectorHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpSelectorHandler.java
index 432cecd..30055bf 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpSelectorHandler.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpSelectorHandler.java
@@ -90,7 +90,9 @@ public class OpSelectorHandler extends MessageToMessageDecoder<RequestMessage> {
else {
// invalid op processor selected so write back an error by way of OpProcessorException.
final String errorMessage = String.format("Invalid OpProcessor requested [%s]", msg.getProcessor());
- throw new OpProcessorException(errorMessage, ResponseMessage.build(msg).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(errorMessage).create());
+ throw new OpProcessorException(errorMessage, ResponseMessage.build(msg)
+ .code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS)
+ .statusMessage(errorMessage).create());
}
} catch (OpProcessorException ope) {
logger.warn(ope.getMessage(), ope);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java
index 80565f1..ecd5159 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java
@@ -25,6 +25,7 @@ import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
import org.apache.tinkerpop.gremlin.driver.ser.MessageTextSerializer;
import org.apache.tinkerpop.gremlin.server.GremlinServer;
import org.apache.tinkerpop.gremlin.server.op.session.Session;
+import org.apache.tinkerpop.gremlin.server.util.ExceptionHelper;
import org.apache.tinkerpop.gremlin.server.util.MetricManager;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
@@ -89,10 +90,10 @@ public class WsGremlinResponseEncoder extends MessageToMessageEncoder<ResponseMe
} catch (Exception ex) {
errorMeter.mark();
logger.warn("The result [{}] in the request {} could not be serialized and returned.", o.getResult(), o.getRequestId(), ex);
- final String errorMessage = String.format("Error during serialization: %s",
- ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage());
+ final String errorMessage = String.format("Error during serialization: %s", ExceptionHelper.getMessageFromExceptionOrCause(ex));
final ResponseMessage error = ResponseMessage.build(o.getRequestId())
.statusMessage(errorMessage)
+ .statusAttributeException(ex)
.code(ResponseStatusCode.SERVER_ERROR_SERIALIZATION).create();
if (useBinary) {
objects.add(new BinaryWebSocketFrame(serializer.serializeResponseAsBinary(error, ctx.alloc())));
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index 1ba6e36..ffbda08 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@ -254,20 +254,25 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
// and by default disabled. we can remove this handling once we drop that setting all together
final String errorMessage = String.format("Response iteration exceeded the configured threshold for request [%s] - %s", msg, ex.getMessage());
logger.warn(errorMessage);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage(errorMessage).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+ .statusMessage(errorMessage)
+ .statusAttributeException(ex).create());
if (managedTransactionsForRequest) attemptRollback(msg, context.getGraphManager(), settings.strictTransactionManagement);
} catch (InterruptedException ex) {
// interruption occurs if there is a forced timeout during result iteration. this timeout
// is driven by the script evaluation timeout so for consistency the message should be the same
final String errorMessage = String.format("Script evaluation exceeded the configured threshold for request [%s] - %s", msg, ex.getMessage());
logger.warn(errorMessage, ex);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage(ex.getMessage()).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+ .statusMessage(ex.getMessage())
+ .statusAttributeException(ex).create());
if (managedTransactionsForRequest) attemptRollback(msg, context.getGraphManager(), settings.strictTransactionManagement);
} catch (Exception ex) {
logger.warn(String.format("Exception processing a script on request [%s].", msg), ex);
final String err = ex.getMessage();
ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR)
- .statusMessage(null == err || err.isEmpty() ? ex.getClass().getSimpleName() : err).create());
+ .statusMessage(null == err || err.isEmpty() ? ex.getClass().getSimpleName() : err)
+ .statusAttributeException(ex).create());
if (managedTransactionsForRequest) attemptRollback(msg, context.getGraphManager(), settings.strictTransactionManagement);
}
}).create();
@@ -284,16 +289,22 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
// occurs when the TimedInterruptCustomizerProvider is in play
final String errorMessage = String.format("A timeout occurred within the script during evaluation of [%s] - consider increasing the limit given to TimedInterruptCustomizerProvider", msg);
logger.warn(errorMessage);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider").create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+ .statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider")
+ .statusAttributeException(t).create());
} else if (t instanceof org.apache.tinkerpop.gremlin.groovy.jsr223.TimedInterruptTimeoutException) {
// occurs when the TimedInterruptCustomizerProvider is in play
final String errorMessage = String.format("A timeout occurred within the script during evaluation of [%s] - consider increasing the limit given to TimedInterruptCustomizerProvider", msg);
logger.warn(errorMessage);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider").create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+ .statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider")
+ .statusAttributeException(t).create());
} else if (t instanceof TimeoutException) {
final String errorMessage = String.format("Script evaluation exceeded the configured threshold for request [%s] - %s", msg, t.getMessage());
logger.warn(errorMessage, t);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage(t.getMessage()).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+ .statusMessage(t.getMessage())
+ .statusAttributeException(t).create());
} else {
// try to trap the specific jvm error of "Method code too large!" to re-write it as something nicer,
// but only re-write if it's the only error because otherwise we might lose some other important
@@ -305,10 +316,14 @@ public abstract class AbstractEvalOpProcessor extends AbstractOpProcessor {
((MultipleCompilationErrorsException) t).getErrorCollector().getErrorCount() == 1) {
final String errorMessage = String.format("The Gremlin statement that was submitted exceed the maximum compilation size allowed by the JVM, please split it into multiple smaller statements - %s", msg);
logger.warn(errorMessage);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION).statusMessage(errorMessage).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION)
+ .statusMessage(errorMessage)
+ .statusAttributeException(t).create());
} else {
logger.warn(String.format("Exception processing a script on request [%s].", msg), t);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION).statusMessage(t.getMessage()).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION)
+ .statusMessage(t.getMessage())
+ .statusAttributeException(t).create());
}
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
index c3ac475..8899bb5 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractOpProcessor.java
@@ -32,6 +32,7 @@ import org.apache.tinkerpop.gremlin.server.OpProcessor;
import org.apache.tinkerpop.gremlin.server.Settings;
import org.apache.tinkerpop.gremlin.server.handler.Frame;
import org.apache.tinkerpop.gremlin.server.handler.StateKey;
+import org.apache.tinkerpop.gremlin.server.util.ExceptionHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -277,10 +278,10 @@ public abstract class AbstractOpProcessor implements OpProcessor {
}
} catch (Exception ex) {
logger.warn("The result [{}] in the request {} could not be serialized and returned.", aggregate, msg.getRequestId(), ex);
- final String errorMessage = String.format("Error during serialization: %s",
- ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage());
+ final String errorMessage = String.format("Error during serialization: %s", ExceptionHelper.getMessageFromExceptionOrCause(ex));
final ResponseMessage error = ResponseMessage.build(msg.getRequestId())
.statusMessage(errorMessage)
+ .statusAttributeException(ex)
.code(ResponseStatusCode.SERVER_ERROR_SERIALIZATION).create();
ctx.writeAndFlush(error);
throw ex;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
index c5a05e4..9d908ca 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
@@ -299,12 +299,16 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
} catch (TimeoutException ex) {
final String errorMessage = String.format("Response iteration exceeded the configured threshold for request [%s] - %s", msg.getRequestId(), ex.getMessage());
logger.warn(errorMessage);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage(errorMessage).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+ .statusMessage(errorMessage)
+ .statusAttributeException(ex).create());
onError(graph, context);
return;
} catch (Exception ex) {
logger.warn(String.format("Exception processing a side-effect on iteration for request [%s].", msg.getRequestId()), ex);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR).statusMessage(ex.getMessage()).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR)
+ .statusMessage(ex.getMessage())
+ .statusAttributeException(ex).create());
onError(graph, context);
return;
}
@@ -312,7 +316,9 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
onSideEffectSuccess(graph, context);
} catch (Exception ex) {
logger.warn(String.format("Exception processing a side-effect on request [%s].", msg.getRequestId()), ex);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR).statusMessage(ex.getMessage()).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR)
+ .statusMessage(ex.getMessage())
+ .statusAttributeException(ex).create());
onError(graph, context);
} finally {
timerContext.stop();
@@ -322,7 +328,9 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
} catch (Exception ex) {
timerContext.stop();
throw new OpProcessorException("Could not iterate the side-effect instance",
- ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR).statusMessage(ex.getMessage()).create());
+ ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR)
+ .statusMessage(ex.getMessage())
+ .statusAttributeException(ex).create());
}
}
@@ -357,7 +365,8 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
logger.error("Could not deserialize the Traversal instance", context);
throw new OpProcessorException("Could not deserialize the Traversal instance",
ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_SERIALIZATION)
- .statusMessage(ex.getMessage()).create());
+ .statusMessage(ex.getMessage())
+ .statusAttributeException(ex).create());
}
final Timer.Context timerContext = traversalOpTimer.time();
@@ -376,18 +385,24 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
} catch (TimeoutException ex) {
final String errorMessage = String.format("Response iteration exceeded the configured threshold for request [%s] - %s", msg.getRequestId(), ex.getMessage());
logger.warn(errorMessage);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage(errorMessage).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+ .statusMessage(errorMessage)
+ .statusAttributeException(ex).create());
onError(graph, context);
return;
} catch (Exception ex) {
logger.warn(String.format("Exception processing a Traversal on iteration for request [%s].", msg.getRequestId()), ex);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR).statusMessage(ex.getMessage()).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR)
+ .statusMessage(ex.getMessage())
+ .statusAttributeException(ex).create());
onError(graph, context);
return;
}
} catch (Exception ex) {
logger.warn(String.format("Exception processing a Traversal on request [%s].", msg.getRequestId()), ex);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR).statusMessage(ex.getMessage()).create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR)
+ .statusMessage(ex.getMessage())
+ .statusAttributeException(ex).create());
onError(graph, context);
} finally {
timerContext.stop();
@@ -397,7 +412,9 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
} catch (Exception ex) {
timerContext.stop();
throw new OpProcessorException("Could not iterate the Traversal instance",
- ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR).statusMessage(ex.getMessage()).create());
+ ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR)
+ .statusMessage(ex.getMessage())
+ .statusAttributeException(ex).create());
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ExceptionHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ExceptionHelper.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ExceptionHelper.java
new file mode 100644
index 0000000..49eb8a6
--- /dev/null
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ExceptionHelper.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.server.util;
+
+/**
+ * Utility class for working with exceptions.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public final class ExceptionHelper {
+
+ private ExceptionHelper() {}
+
+ public static String getMessageOrName(final Throwable t) {
+ return (null == t.getMessage() || t.getMessage().isEmpty()) ?
+ t.getClass().getName() : t.getMessage();
+ }
+
+ public static String getMessageFromExceptionOrCause(final Throwable t) {
+ return null == t.getCause() ? getMessageOrName(t) : getMessageOrName(t.getCause());
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
index a8164b5..9eabf15 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
@@ -363,6 +363,11 @@ public class GremlinDriverIntegrateTest extends AbstractGremlinServerIntegration
final Throwable inner = ExceptionUtils.getRootCause(ex);
assertTrue(inner instanceof ResponseException);
assertThat(inner.getMessage(), endsWith("Division by zero"));
+
+ final ResponseException rex = (ResponseException) inner;
+ assertEquals("java.lang.ArithmeticException", rex.getRemoteExceptionHierarchy().get().get(0));
+ assertEquals(1, rex.getRemoteExceptionHierarchy().get().size());
+ assertThat(rex.getRemoteStackTrace().get(), startsWith("java.lang.ArithmeticException: Division by zero\n\tat java.math.BigDecimal.divide(BigDecimal.java:1742)\n\tat org.codehaus.groovy.runtime.typehandling.BigDecimalMath.divideImpl(BigDecimalMath.java:68)\n\tat org.codehaus.groovy.runtime.typehandling.IntegerMath.divideImpl(IntegerMath.java:49)\n\tat org.codehaus.groovy.runtime.dgmimpl.NumberNumberDiv$NumberNumber.invoke(NumberNumberDiv.java:323)\n\tat org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)\n\tat org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)\n\tat org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)\n\tat org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)\n"));
}
// should not die completely just because we had a bad serialization error. that kind of stuff happens
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b29bab0a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
index 78109e6..b1cbd7f 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
@@ -18,6 +18,7 @@
*/
package org.apache.tinkerpop.gremlin.server;
+import org.apache.tinkerpop.gremlin.driver.Tokens;
import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0;
import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator;
import org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer;
@@ -42,6 +43,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.StringStartsWith.startsWith;
import static org.junit.Assert.assertEquals;
/**
@@ -799,6 +802,11 @@ public class GremlinServerHttpIntegrateTest extends AbstractGremlinServerIntegra
try (final CloseableHttpResponse response = httpclient.execute(httppost)) {
assertEquals(500, response.getStatusLine().getStatusCode());
+ final String json = EntityUtils.toString(response.getEntity());
+ final JsonNode node = mapper.readTree(json);
+ assertEquals("java.lang.ArithmeticException", node.get(Tokens.STATUS_ATTRIBUTE_EXCEPTIONS).get(0).asText());
+ assertEquals(1, node.get(Tokens.STATUS_ATTRIBUTE_EXCEPTIONS).size());
+ assertThat(node.get(Tokens.STATUS_ATTRIBUTE_STACK_TRACE).asText(), startsWith("java.lang.ArithmeticException: Division by zero\n\tat java.math.BigDecimal.divide(BigDecimal.java:1742)\n\tat org.codehaus.groovy.runtime.typehandling.BigDecimalMath.divideImpl(BigDecimalMath.java:68)\n\tat org.codehaus.groovy.runtime.typehandling.IntegerMath.divideImpl(IntegerMath.java:49)\n\tat org.codehaus.groovy.runtime.dgmimpl.NumberNumberDiv$NumberNumber.invoke(NumberNumberDiv.java:323)\n\tat org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)\n\tat org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)\n\tat org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)\n\tat org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)\n"));
}
}
[4/6] tinkerpop git commit: Merge branch 'TINKERPOP-1044' into tp32
Posted by sp...@apache.org.
Merge branch 'TINKERPOP-1044' into tp32
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/1fc841cf
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/1fc841cf
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/1fc841cf
Branch: refs/heads/master
Commit: 1fc841cf25894646137f5dc69701539ba5a885a9
Parents: 1e349c8 c33069c
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Apr 18 15:18:38 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Apr 18 15:18:38 2017 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 2 ++
.../upgrade/release-3.2.x-incubating.asciidoc | 35 ++++++++++++++++++
.../tinkerpop/gremlin/driver/Handler.java | 11 ++++--
.../apache/tinkerpop/gremlin/driver/Tokens.java | 3 ++
.../driver/exception/ResponseException.java | 27 ++++++++++++++
.../gremlin/driver/message/ResponseMessage.java | 19 ++++++++++
.../gremlin/driver/ResultQueueTest.java | 2 --
.../handler/GremlinResponseFrameEncoder.java | 6 ++--
.../handler/HttpGremlinEndpointHandler.java | 9 +++--
.../gremlin/server/handler/IteratorHandler.java | 5 ++-
.../handler/NioGremlinResponseEncoder.java | 5 +--
.../server/handler/OpExecutorHandler.java | 1 +
.../server/handler/OpSelectorHandler.java | 4 ++-
.../handler/WsGremlinResponseEncoder.java | 5 +--
.../server/op/AbstractEvalOpProcessor.java | 31 +++++++++++-----
.../gremlin/server/op/AbstractOpProcessor.java | 5 +--
.../op/traversal/TraversalOpProcessor.java | 35 +++++++++++++-----
.../gremlin/server/util/ExceptionHelper.java | 38 ++++++++++++++++++++
.../server/GremlinDriverIntegrateTest.java | 5 +++
.../server/GremlinServerHttpIntegrateTest.java | 8 +++++
20 files changed, 223 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1fc841cf/CHANGELOG.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1fc841cf/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1fc841cf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1fc841cf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1fc841cf/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1fc841cf/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1fc841cf/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
----------------------------------------------------------------------
[6/6] tinkerpop git commit: Merge branch 'tp32'
Posted by sp...@apache.org.
Merge branch 'tp32'
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/00057b9b
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/00057b9b
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/00057b9b
Branch: refs/heads/master
Commit: 00057b9b118db2011da306b09ee6b304930835e4
Parents: 0eba268 1fc841c
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Apr 18 15:20:05 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Apr 18 15:20:05 2017 -0400
----------------------------------------------------------------------
----------------------------------------------------------------------
[2/6] tinkerpop git commit: TINKERPOP-1044 Added documentation for
additional error info in ResponseMessage
Posted by sp...@apache.org.
TINKERPOP-1044 Added documentation for additional error info in ResponseMessage
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/c33069ce
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/c33069ce
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/c33069ce
Branch: refs/heads/master
Commit: c33069cecd227dff664a02330a8462efce32e121
Parents: b29bab0
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Apr 6 18:10:08 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Apr 6 18:10:08 2017 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 2 ++
.../upgrade/release-3.2.x-incubating.asciidoc | 35 ++++++++++++++++++++
.../driver/exception/ResponseException.java | 7 ++++
3 files changed, 44 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c33069ce/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 19d1d59..00ada7e 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -31,6 +31,8 @@ TinkerPop 3.2.5 (Release Date: NOT OFFICIALLY RELEASED YET)
* `ProfileStrategy` now uses the marker-model to reduce recursive lookups of `ProfileSideEffectStep`.
* `Mutating` steps now implement `Scoping` interface.
* Fixed a step id compilation bug in `AddVertexStartStep`, `AddVertexStep`, `AddEdgeStep`, and `AddPropertyStep`.
+* Added more details to Gremlin Server client side messages - exception hierarchy and stack trace.
+* Deprecated "Exception-Class" in the Gremlin Server HTTP protocol in favor of the new "exceptions" field.
* De-registered metrics on Gremlin Server shutdown.
* Added "help" command option on `:remote config` for plugins that support that feature in the Gremlin Console.
* Allowed for multiple scripts and related arguments to be passed to `gremlin.sh` via `-i` and `-e`.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c33069ce/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index fbe31bd..4324578 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -42,6 +42,41 @@ set. Note that metrics are captured for both sessionless requests as well as for
See: https://issues.apache.org/jira/browse/TINKERPOP-1644[TINKERPOP-1644]
+Additional Error Information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Additional information on error responses from Gremlin Server should help make debugging errors easier. Error responses
+now have both the exception hierarchy and the stack trace that was generated on the server. In this way, receiving an
+error on a client doesn't mean having to rifle through Gremlin Server logs to try to find the associated error.
+
+This change has been applied to all Gremlin Server protocols. For the binary protocol and the Java driver this change
+means that the `ResponseException` thrown from calls to `submit()` requests to the server now have the following
+methods:
+
+[source,java]
+----
+public Optional<String> getRemoteStackTrace()
+
+public Optional<List<String>> getRemoteExceptionHierarchy()
+----
+
+The HTTP protocol has also been updated and returns both `exceptions` and `stackTrace` fields in the response:
+
+[source,js]
+----
+{
+ "message": "Division by zero",
+ "Exception-Class": "java.lang.ArithmeticException",
+ "exceptions": ["java.lang.ArithmeticException"],
+ "stackTrace": "java.lang.ArithmeticException: Division by zero\n\tat java.math.BigDecimal.divide(BigDecimal.java:1742)\n\tat org.codehaus.groovy.runtime.typehandling.BigDecimalMath.divideImpl(BigDecimalMath.java:68)\n\tat org.codehaus.groovy.runtime.typehandling.IntegerMath.divideImpl(IntegerMath.java:49)\n\tat org.codehaus.groovy.runtime.dgmimpl.NumberNumberDiv$NumberNumber.invoke(NumberNumberDiv.java:323)\n\tat org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)\n\tat org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)\n\tat org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)\n\tat org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)\n\tat Script4.run(Script4.groovy:1)\n\tat org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine.eval(GremlinGroovyScriptEngine.java:834)\n\tat org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovy
ScriptEngine.eval(GremlinGroovyScriptEngine.java:547)\n\tat javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233)\n\tat org.apache.tinkerpop.gremlin.groovy.engine.ScriptEngines.eval(ScriptEngines.java:120)\n\tat org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor.lambda$eval$2(GremlinExecutor.java:314)\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)\n\tat java.lang.Thread.run(Thread.java:745)\n"
+}
+----
+
+Note that the `Exception-Class` which was added in a previous version has been deprecated and replaced by these new
+fields.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1044[TINKERPOP-1044]
+
Gremlin Console Scripting
^^^^^^^^^^^^^^^^^^^^^^^^^
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c33069ce/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java
index 800c2fc..51e748a 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/exception/ResponseException.java
@@ -47,10 +47,17 @@ public class ResponseException extends Exception {
return responseStatusCode;
}
+ /**
+ * The stacktrace produced by the remote server.
+ */
public Optional<String> getRemoteStackTrace() {
return Optional.ofNullable(remoteStackTrace);
}
+ /**
+ * The list of exceptions generated by the server starting with the top-most one followed by its "cause". That
+ * cause is then followed by its cause and so on down the line.
+ */
public Optional<List<String>> getRemoteExceptionHierarchy() {
return Optional.ofNullable(remoteExceptionHierarchy);
}
[3/6] tinkerpop git commit: Merge branch 'TINKERPOP-1044' into
TINKERPOP-1044-master
Posted by sp...@apache.org.
Merge branch 'TINKERPOP-1044' into TINKERPOP-1044-master
Conflicts:
gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/92eceb4e
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/92eceb4e
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/92eceb4e
Branch: refs/heads/master
Commit: 92eceb4e620409be2c9ee810cc4132b7ae2dafc7
Parents: bc4cf2b c33069c
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Apr 7 08:22:31 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Apr 7 08:22:31 2017 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 2 ++
.../upgrade/release-3.2.x-incubating.asciidoc | 35 ++++++++++++++++++
.../tinkerpop/gremlin/driver/Handler.java | 11 ++++--
.../apache/tinkerpop/gremlin/driver/Tokens.java | 3 ++
.../driver/exception/ResponseException.java | 27 ++++++++++++++
.../gremlin/driver/message/ResponseMessage.java | 19 ++++++++++
.../gremlin/driver/ResultQueueTest.java | 2 --
.../handler/GremlinResponseFrameEncoder.java | 6 ++--
.../handler/HttpGremlinEndpointHandler.java | 9 +++--
.../gremlin/server/handler/IteratorHandler.java | 5 ++-
.../handler/NioGremlinResponseEncoder.java | 5 +--
.../server/handler/OpExecutorHandler.java | 1 +
.../server/handler/OpSelectorHandler.java | 4 ++-
.../handler/WsGremlinResponseEncoder.java | 5 +--
.../server/op/AbstractEvalOpProcessor.java | 27 ++++++++++----
.../gremlin/server/op/AbstractOpProcessor.java | 5 +--
.../op/traversal/TraversalOpProcessor.java | 35 +++++++++++++-----
.../gremlin/server/util/ExceptionHelper.java | 38 ++++++++++++++++++++
.../server/GremlinDriverIntegrateTest.java | 5 +++
.../server/GremlinServerHttpIntegrateTest.java | 8 +++++
20 files changed, 220 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/92eceb4e/CHANGELOG.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/92eceb4e/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/92eceb4e/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Handler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/92eceb4e/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/92eceb4e/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index 13e5968,ffbda08..33e8108
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@@ -290,8 -288,17 +295,10 @@@ public abstract class AbstractEvalOpPro
} else if (t instanceof TimedInterruptTimeoutException) {
// occurs when the TimedInterruptCustomizerProvider is in play
final String errorMessage = String.format("A timeout occurred within the script during evaluation of [%s] - consider increasing the limit given to TimedInterruptCustomizerProvider", msg);
- logger.warn(errorMessage);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
- .statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider")
- .statusAttributeException(t).create());
- } else if (t instanceof org.apache.tinkerpop.gremlin.groovy.jsr223.TimedInterruptTimeoutException) {
- // occurs when the TimedInterruptCustomizerProvider is in play
- final String errorMessage = String.format("A timeout occurred within the script during evaluation of [%s] - consider increasing the limit given to TimedInterruptCustomizerProvider", msg);
logger.warn(errorMessage);
- ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT).statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider").create());
+ ctx.writeAndFlush(ResponseMessage.build(msg).code(ResponseStatusCode.SERVER_ERROR_TIMEOUT)
+ .statusMessage("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider")
+ .statusAttributeException(t).create());
} else if (t instanceof TimeoutException) {
final String errorMessage = String.format("Script evaluation exceeded the configured threshold for request [%s] - %s", msg, t.getMessage());
logger.warn(errorMessage, t);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/92eceb4e/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/92eceb4e/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/92eceb4e/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
index 9cea2ce,b1cbd7f..0d4f49c
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
@@@ -18,10 -18,8 +18,11 @@@
*/
package org.apache.tinkerpop.gremlin.server;
+import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0;
+ import org.apache.tinkerpop.gremlin.driver.Tokens;
import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0;
+import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0;
+import org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin;
import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator;
import org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer;
import org.apache.http.Consts;
[5/6] tinkerpop git commit: Merge branch 'TINKERPOP-1044-master'
Posted by sp...@apache.org.
Merge branch 'TINKERPOP-1044-master'
Conflicts:
gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/IteratorHandler.java
gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/NioGremlinResponseEncoder.java
gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/WsGremlinResponseEncoder.java
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/0eba268b
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/0eba268b
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/0eba268b
Branch: refs/heads/master
Commit: 0eba268b4f0f3ce856098d11dbff453929734cfa
Parents: 3d857cb 92eceb4
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Apr 18 15:20:00 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Apr 18 15:20:00 2017 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 2 ++
.../upgrade/release-3.2.x-incubating.asciidoc | 35 ++++++++++++++++++
.../tinkerpop/gremlin/driver/Handler.java | 11 ++++--
.../apache/tinkerpop/gremlin/driver/Tokens.java | 3 ++
.../driver/exception/ResponseException.java | 27 ++++++++++++++
.../gremlin/driver/message/ResponseMessage.java | 19 ++++++++++
.../gremlin/driver/ResultQueueTest.java | 2 --
.../handler/GremlinResponseFrameEncoder.java | 6 ++--
.../handler/HttpGremlinEndpointHandler.java | 9 +++--
.../server/handler/OpExecutorHandler.java | 1 +
.../server/handler/OpSelectorHandler.java | 4 ++-
.../server/op/AbstractEvalOpProcessor.java | 27 ++++++++++----
.../gremlin/server/op/AbstractOpProcessor.java | 5 +--
.../op/traversal/TraversalOpProcessor.java | 35 +++++++++++++-----
.../gremlin/server/util/ExceptionHelper.java | 38 ++++++++++++++++++++
.../server/GremlinDriverIntegrateTest.java | 5 +++
.../server/GremlinServerHttpIntegrateTest.java | 8 +++++
17 files changed, 210 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0eba268b/CHANGELOG.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0eba268b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0eba268b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0eba268b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/OpSelectorHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0eba268b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0eba268b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0eba268b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0eba268b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java
----------------------------------------------------------------------