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 c66659cff..5236db6b1 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 @@ 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 T read(Object jsonObject, Configuration configuration) { } } 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 000000000..2ef45bf0c --- /dev/null +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/FastPathNotFoundException.java @@ -0,0 +1,29 @@ +package com.jayway.jsonpath.internal; + +import com.jayway.jsonpath.PathNotFoundException; + +/** + * 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 PathNotFoundException { + + 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/path/EvaluationContextImpl.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java index 3fc7e4873..8707688d6 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 @@ 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 T getValue() { 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 T getValue(boolean unwrap) { @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; }