diff --git a/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java b/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java index c66659cf..5236db6b 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java +++ b/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java @@ -16,6 +16,7 @@ package com.jayway.jsonpath; import com.jayway.jsonpath.internal.EvaluationContext; +import com.jayway.jsonpath.internal.FastPathNotFoundException; import com.jayway.jsonpath.internal.ParseContextImpl; import com.jayway.jsonpath.internal.Path; import com.jayway.jsonpath.internal.PathRef; @@ -195,6 +196,11 @@ public class JsonPath { } } catch (RuntimeException e) { if (!optSuppressExceptions) { + if (e instanceof FastPathNotFoundException) { + // the caller wants an exception -> convert the stacktrace-less FastPathNotFoundException + // into one with stacktrace + throw new PathNotFoundException(e.getMessage()); + } throw e; } else { if (optAsPathList) { diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/FastPathNotFoundException.java b/json-path/src/main/java/com/jayway/jsonpath/internal/FastPathNotFoundException.java new file mode 100644 index 00000000..130a50f5 --- /dev/null +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/FastPathNotFoundException.java @@ -0,0 +1,27 @@ +package com.jayway.jsonpath.internal; + +/** + * An alternative to {@link com.jayway.jsonpath.PathNotFoundException} but without stacktrace. + * Throwing an exception can be very expensive because of {@link Throwable#fillInStackTrace()}. + * This can be a performance issue. It is pointless to generate stacktrace when + * {@link com.jayway.jsonpath.Option#SUPPRESS_EXCEPTIONS} is active. + */ +public class FastPathNotFoundException extends RuntimeException { + + public FastPathNotFoundException(String message) { + super(message); + } + + public FastPathNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public FastPathNotFoundException(Throwable cause) { + super(cause); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } +} diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java index d1619c45..d092759e 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java @@ -6,6 +6,7 @@ import com.jayway.jsonpath.JsonPathException; import com.jayway.jsonpath.Option; import com.jayway.jsonpath.PathNotFoundException; import com.jayway.jsonpath.Predicate; +import com.jayway.jsonpath.internal.FastPathNotFoundException; import com.jayway.jsonpath.internal.Path; import com.jayway.jsonpath.internal.Utils; import com.jayway.jsonpath.internal.path.PathCompiler; @@ -825,6 +826,8 @@ public abstract class ValueNode { return result == JsonProvider.UNDEFINED ? ValueNode.FALSE : ValueNode.TRUE; } catch (PathNotFoundException e) { return ValueNode.FALSE; + } catch (FastPathNotFoundException e) { + return ValueListNode.FALSE; } } else { try { diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java index 3fc7e487..8707688d 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java @@ -17,9 +17,9 @@ package com.jayway.jsonpath.internal.path; import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.EvaluationListener; import com.jayway.jsonpath.Option; -import com.jayway.jsonpath.PathNotFoundException; import com.jayway.jsonpath.internal.EvaluationAbortException; import com.jayway.jsonpath.internal.EvaluationContext; +import com.jayway.jsonpath.internal.FastPathNotFoundException; import com.jayway.jsonpath.internal.Path; import com.jayway.jsonpath.internal.PathRef; import com.jayway.jsonpath.spi.json.JsonProvider; @@ -130,7 +130,7 @@ public class EvaluationContextImpl implements EvaluationContext { public T getValue(boolean unwrap) { if (path.isDefinite()) { if(resultIndex == 0){ - throw new PathNotFoundException("No results for path: " + path.toString()); + throw new FastPathNotFoundException("No results for path: " + path.toString()); } int len = jsonProvider().length(valueResult); Object value = (len > 0) ? jsonProvider().getArrayIndex(valueResult, len-1) : null; @@ -146,7 +146,7 @@ public class EvaluationContextImpl implements EvaluationContext { @Override public T getPath() { if(resultIndex == 0){ - throw new PathNotFoundException("No results for path: " + path.toString()); + throw new FastPathNotFoundException("No results for path: " + path.toString()); } return (T)pathResult; }