Skip to content

Commit

Permalink
Do not throw exceptions when resolving paths in ingest documents (ela…
Browse files Browse the repository at this point in the history
  • Loading branch information
danhermann committed Mar 4, 2022
1 parent 8322809 commit 7e8663a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 23 deletions.
5 changes: 5 additions & 0 deletions docs/changelog/84659.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 84659
summary: Do not throw exceptions when resolving paths in ingest documents
area: Ingest
type: enhancement
issues: []
70 changes: 47 additions & 23 deletions server/src/main/java/org/elasticsearch/ingest/IngestDocument.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,12 @@ public IngestDocument(Map<String, Object> sourceAndMetadata, Map<String, Object>
* Returns the value contained in the document for the provided path
* @param path The path within the document in dot-notation
* @param clazz The expected class of the field value
* @return the value for the provided path if existing, null otherwise
* @return the value for the provided path if existing
* @throws IllegalArgumentException if the path is null, empty, invalid, if the field doesn't exist
* or if the field that is found at the provided path is not of the expected type.
*/
public <T> T getFieldValue(String path, Class<T> clazz) {
FieldPath fieldPath = new FieldPath(path);
Object context = fieldPath.initialContext;
for (String pathElement : fieldPath.pathElements) {
context = resolve(pathElement, path, context);
}
return cast(path, context, clazz);
return getFieldValue(path, clazz, false);
}

/**
Expand All @@ -118,15 +113,19 @@ public <T> T getFieldValue(String path, Class<T> clazz) {
* or if the field that is found at the provided path is not of the expected type.
*/
public <T> T getFieldValue(String path, Class<T> clazz, boolean ignoreMissing) {
try {
return getFieldValue(path, clazz);
} catch (IllegalArgumentException e) {
if (ignoreMissing && hasField(path) != true) {
FieldPath fieldPath = new FieldPath(path);
Object context = fieldPath.initialContext;
for (String pathElement : fieldPath.pathElements) {
ResolveResult result = resolve(pathElement, path, context);
if (result.wasSuccessful) {
context = result.resolvedObject;
} else if (ignoreMissing && hasField(path) == false) {
return null;
} else {
throw e;
throw new IllegalArgumentException(result.errorMessage);
}
}
return cast(path, context, clazz);
}

/**
Expand Down Expand Up @@ -287,7 +286,12 @@ public void removeField(String path) {
FieldPath fieldPath = new FieldPath(path);
Object context = fieldPath.initialContext;
for (int i = 0; i < fieldPath.pathElements.length - 1; i++) {
context = resolve(fieldPath.pathElements[i], path, context);
ResolveResult result = resolve(fieldPath.pathElements[i], path, context);
if (result.wasSuccessful) {
context = result.resolvedObject;
} else {
throw new IllegalArgumentException(result.errorMessage);
}
}

String leafKey = fieldPath.pathElements[fieldPath.pathElements.length - 1];
Expand Down Expand Up @@ -325,34 +329,33 @@ public void removeField(String path) {
);
}

private static Object resolve(String pathElement, String fullPath, Object context) {
private static ResolveResult resolve(String pathElement, String fullPath, Object context) {
if (context == null) {
throw new IllegalArgumentException("cannot resolve [" + pathElement + "] from null as part of path [" + fullPath + "]");
return ResolveResult.error("cannot resolve [" + pathElement + "] from null as part of path [" + fullPath + "]");
}
if (context instanceof Map<?, ?> map) {
if (map.containsKey(pathElement)) {
return map.get(pathElement);
return ResolveResult.success(map.get(pathElement));
}
throw new IllegalArgumentException("field [" + pathElement + "] not present as part of path [" + fullPath + "]");
return ResolveResult.error("field [" + pathElement + "] not present as part of path [" + fullPath + "]");
}
if (context instanceof List<?> list) {
int index;
try {
index = Integer.parseInt(pathElement);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
"[" + pathElement + "] is not an integer, cannot be used as an index as part of path [" + fullPath + "]",
e
return ResolveResult.error(
"[" + pathElement + "] is not an integer, cannot be used as an index as part of path [" + fullPath + "]"
);
}
if (index < 0 || index >= list.size()) {
throw new IllegalArgumentException(
return ResolveResult.error(
"[" + index + "] is out of bounds for array with length [" + list.size() + "] as part of path [" + fullPath + "]"
);
}
return list.get(index);
return ResolveResult.success(list.get(index));
}
throw new IllegalArgumentException(
return ResolveResult.error(
"cannot resolve ["
+ pathElement
+ "] from object of type ["
Expand Down Expand Up @@ -892,4 +895,25 @@ private FieldPath(String path) {
}

}

private static class ResolveResult {
boolean wasSuccessful;
String errorMessage;
Object resolvedObject;

static ResolveResult success(Object resolvedObject) {
ResolveResult result = new ResolveResult();
result.wasSuccessful = true;
result.resolvedObject = resolvedObject;
return result;
}

static ResolveResult error(String errorMessage) {
ResolveResult result = new ResolveResult();
result.wasSuccessful = false;
result.errorMessage = errorMessage;
return result;

}
}
}

0 comments on commit 7e8663a

Please sign in to comment.