|
@@ -1,6 +1,7 @@
|
|
|
package org.elasticsearch.script;
|
|
|
|
|
|
import org.elasticsearch.ElasticsearchException;
|
|
|
+import org.elasticsearch.Version;
|
|
|
import org.elasticsearch.common.Strings;
|
|
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
|
@@ -51,6 +52,7 @@ public class ScriptException extends ElasticsearchException {
|
|
|
private final List<String> scriptStack;
|
|
|
private final String script;
|
|
|
private final String lang;
|
|
|
+ private final Position pos;
|
|
|
|
|
|
/**
|
|
|
* Create a new ScriptException.
|
|
@@ -61,13 +63,22 @@ public class ScriptException extends ElasticsearchException {
|
|
|
* Must not be {@code null}, but can be empty (though this should be avoided if possible).
|
|
|
* @param script Identifier for which script failed. Must not be {@code null}.
|
|
|
* @param lang Scripting engine language, such as "painless". Must not be {@code null}.
|
|
|
- * @throws NullPointerException if any parameters are {@code null}.
|
|
|
+ * @param pos Position of error within script, may be {@code null}.
|
|
|
+ * @throws NullPointerException if any parameters are {@code null} except pos.
|
|
|
*/
|
|
|
- public ScriptException(String message, Throwable cause, List<String> scriptStack, String script, String lang) {
|
|
|
+ public ScriptException(String message, Throwable cause, List<String> scriptStack, String script, String lang, Position pos) {
|
|
|
super(Objects.requireNonNull(message), Objects.requireNonNull(cause));
|
|
|
this.scriptStack = Collections.unmodifiableList(Objects.requireNonNull(scriptStack));
|
|
|
this.script = Objects.requireNonNull(script);
|
|
|
this.lang = Objects.requireNonNull(lang);
|
|
|
+ this.pos = pos;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Create a new ScriptException with null Position.
|
|
|
+ */
|
|
|
+ public ScriptException(String message, Throwable cause, List<String> scriptStack, String script, String lang) {
|
|
|
+ this(message, cause, scriptStack, script, lang, null);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -78,6 +89,11 @@ public class ScriptException extends ElasticsearchException {
|
|
|
scriptStack = Arrays.asList(in.readStringArray());
|
|
|
script = in.readString();
|
|
|
lang = in.readString();
|
|
|
+ if (in.getVersion().onOrAfter(Version.V_7_7_0) && in.readBoolean()) {
|
|
|
+ pos = new Position(in);
|
|
|
+ } else {
|
|
|
+ pos = null;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -86,6 +102,14 @@ public class ScriptException extends ElasticsearchException {
|
|
|
out.writeStringArray(scriptStack.toArray(new String[0]));
|
|
|
out.writeString(script);
|
|
|
out.writeString(lang);
|
|
|
+ if (out.getVersion().onOrAfter(Version.V_7_7_0)) {
|
|
|
+ if (pos == null) {
|
|
|
+ out.writeBoolean(false);
|
|
|
+ } else {
|
|
|
+ out.writeBoolean(true);
|
|
|
+ pos.writeTo(out);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -93,6 +117,9 @@ public class ScriptException extends ElasticsearchException {
|
|
|
builder.field("script_stack", scriptStack);
|
|
|
builder.field("script", script);
|
|
|
builder.field("lang", lang);
|
|
|
+ if (pos != null) {
|
|
|
+ pos.toXContent(builder, params);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -119,6 +146,13 @@ public class ScriptException extends ElasticsearchException {
|
|
|
return lang;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the position of the error.
|
|
|
+ */
|
|
|
+ public Position getPos() {
|
|
|
+ return pos;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Returns a JSON version of this exception for debugging.
|
|
|
*/
|
|
@@ -138,4 +172,51 @@ public class ScriptException extends ElasticsearchException {
|
|
|
public RestStatus status() {
|
|
|
return RestStatus.BAD_REQUEST;
|
|
|
}
|
|
|
+
|
|
|
+ public static class Position {
|
|
|
+ public final int offset;
|
|
|
+ public final int start;
|
|
|
+ public final int end;
|
|
|
+
|
|
|
+ public Position(int offset, int start, int end) {
|
|
|
+ this.offset = offset;
|
|
|
+ this.start = start;
|
|
|
+ this.end = end;
|
|
|
+ }
|
|
|
+
|
|
|
+ Position(StreamInput in) throws IOException {
|
|
|
+ offset = in.readInt();
|
|
|
+ start = in.readInt();
|
|
|
+ end = in.readInt();
|
|
|
+ }
|
|
|
+
|
|
|
+ void writeTo(StreamOutput out) throws IOException {
|
|
|
+ out.writeInt(offset);
|
|
|
+ out.writeInt(start);
|
|
|
+ out.writeInt(end);
|
|
|
+ }
|
|
|
+
|
|
|
+ void toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
|
+ builder.startObject("position");
|
|
|
+ builder.field("offset", offset);
|
|
|
+ builder.field("start", start);
|
|
|
+ builder.field("end", end);
|
|
|
+ builder.endObject();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean equals(Object o) {
|
|
|
+ if (this == o)
|
|
|
+ return true;
|
|
|
+ if (o == null || getClass() != o.getClass())
|
|
|
+ return false;
|
|
|
+ Position position = (Position) o;
|
|
|
+ return offset == position.offset && start == position.start && end == position.end;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int hashCode() {
|
|
|
+ return Objects.hash(offset, start, end);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|