diff --git a/dependencies/pom.xml b/dependencies/pom.xml
index 4508463f025..53548034d1a 100644
--- a/dependencies/pom.xml
+++ b/dependencies/pom.xml
@@ -58,8 +58,8 @@
2.3.33.21.722.3.0
- 18.6
- 18.3
+ 22.1
+ 22.02.9.01.60.032.0.1-jre
diff --git a/graphql/server/src/main/java/io/helidon/graphql/server/InvocationHandlerImpl.java b/graphql/server/src/main/java/io/helidon/graphql/server/InvocationHandlerImpl.java
index ba8a81b37ec..52901a9d1dc 100644
--- a/graphql/server/src/main/java/io/helidon/graphql/server/InvocationHandlerImpl.java
+++ b/graphql/server/src/main/java/io/helidon/graphql/server/InvocationHandlerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2021 Oracle and/or its affiliates.
+ * Copyright (c) 2020, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package io.helidon.graphql.server;
+import java.lang.System.Logger.Level;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -25,8 +26,8 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import graphql.ExceptionWhileDataFetching;
import graphql.ExecutionInput;
@@ -49,7 +50,12 @@
import static io.helidon.graphql.server.GraphQlConstants.PATH;
class InvocationHandlerImpl implements InvocationHandler {
- private static final Logger LOGGER = Logger.getLogger(InvocationHandlerImpl.class.getName());
+ private static final System.Logger LOGGER = System.getLogger(InvocationHandlerImpl.class.getName());
+ private static final Pattern VALIDATION_ERROR_PATTERN = Pattern.compile("Validation error \\((\\w+)@\\[(.*)]\\) : (.*$)");
+ private static final Pattern ERROR_ENUM_REPLACE_PATTERN =
+ Pattern.compile("Literal value not in allowable values for enum '.*?' - ('.*\\{.*}')");
+ private static final Pattern INVALID_TYPE_REPLACE_PATTERN =
+ Pattern.compile("- Expected an AST type of ('.*?') but it was a ('.*?') (@.*?)$");
private final String defaultErrorMessage;
private final Set exceptionDenySet = new HashSet<>();
@@ -76,7 +82,7 @@ public Map execute(String query, String operationName, Map result = new HashMap<>();
addError(result, e, e.getMessage());
return result;
@@ -202,7 +208,71 @@ private void addError(Map resultMap,
path = listPath.get(0).toString();
}
- addErrorPayload(resultMap, error.getMessage(), path, line, column, error.getExtensions());
+ addErrorPayload(resultMap, fixMessage(error.getMessage()), path, line, column, error.getExtensions());
+ }
+
+ // this works around https://github.com/eclipse/microprofile-graphql/issues/520
+ // once the TCK is fixed, we can remove this work-around
+ // this is depending on version of GraphQL (heavily), and any change in error message format
+ // will result in wrong responses
+ private String fixMessage(String message) {
+ if (!message.startsWith("Validation error")) {
+ return message;
+ }
+ /*
+ What we get (first) and what we want (second)
+ Validation error (FieldUndefined@[allHeroes/weaknesses]) : Field 'weaknesses' in type 'SuperHero' is undefined
+ Validation error of type FieldUndefined: Field 'weaknesses' in type 'SuperHero' is undefined @ 'allHeroes/weaknesses'
+ */
+ /*
+ 1: type of error (FieldUndefined)
+ 2: path (allHeroes/weaknesses)
+ 3: Message (Field 'weaknesses' in type 'SuperHero' is undefined)
+ */
+ Matcher matcher = VALIDATION_ERROR_PATTERN.matcher(message);
+ if (matcher.matches()) {
+ String fixedMessage = "Validation error of type " + matcher.group(1)
+ + ": " + matcher.group(3)
+ + " @ '" + matcher.group(2) + "'";
+
+ if (fixedMessage.contains("Literal value not in allowable values for enum")) {
+ /*
+ What we get (first) and what we want (second)
+ Validation error (WrongType@[createNewHero]) : argument 'hero.tshirtSize' with value 'EnumValue{name='XLTall'}'
+ is not a valid 'ShirtSize' - Literal value not in allowable values for enum 'ShirtSize'
+ - 'EnumValue{name='XLTall'}'
+ Validation error of type WrongType: argument 'hero.tshirtSize' with value 'EnumValue{name='XLTall'}' is not a valid
+ 'ShirtSize' - Expected enum literal value not in allowable values
+ - 'EnumValue{name='XLTall'}'. @ 'createNewHero'
+ */
+ // enum failures
+ return ERROR_ENUM_REPLACE_PATTERN.matcher(fixedMessage)
+ .replaceAll("Expected enum literal value not in allowable values - $1.");
+ }
+
+ /*
+ actual graphql message
+ fixed graphql message
+ expected graphql message
+ Validation error (WrongType@[updateItemPowerLevel]) : argument 'powerLevel' with value
+ 'StringValue{value='Unlimited'}' is not a valid 'Int' -
+ Expected an AST type of 'IntValue' but it was a 'StringValue'
+ Validation error of type WrongType: argument 'powerLevel' with value 'StringValue{value='Unlimited'}'
+ is not a valid 'Int' - Expected an AST type of 'IntValue' but it
+ was a 'StringValue' @ 'updateItemPowerLevel'
+ Validation error of type WrongType: argument 'powerLevel' with value 'StringValue{value='Unlimited'}'
+ is not a valid 'Int' - Expected AST type 'IntValue' but
+ was 'StringValue'. @ 'updateItemPowerLevel
+ */
+ if (fixedMessage.contains("type WrongType")) {
+ return INVALID_TYPE_REPLACE_PATTERN.matcher(fixedMessage)
+ .replaceAll("- Expected AST type $1 but was $2. $3");
+ }
+
+ return fixedMessage;
+ } else {
+ return message;
+ }
}
@SuppressWarnings("unchecked")
diff --git a/microprofile/graphql/server/src/main/java/io/helidon/microprofile/graphql/server/DataFetcherUtils.java b/microprofile/graphql/server/src/main/java/io/helidon/microprofile/graphql/server/DataFetcherUtils.java
index 5403faaa3d0..c9b1c07c58e 100644
--- a/microprofile/graphql/server/src/main/java/io/helidon/microprofile/graphql/server/DataFetcherUtils.java
+++ b/microprofile/graphql/server/src/main/java/io/helidon/microprofile/graphql/server/DataFetcherUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2021 Oracle and/or its affiliates.
+ * Copyright (c) 2020, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
+import java.util.function.Supplier;
import java.util.logging.Logger;
import io.helidon.graphql.server.ExecutionContext;
@@ -48,6 +49,7 @@
import graphql.GraphQLException;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
+import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.PropertyDataFetcher;
import graphql.schema.PropertyDataFetcherHelper;
import jakarta.enterprise.inject.spi.CDI;
@@ -192,7 +194,7 @@ static DataFetcher> newMapValuesDataFetcher(String property
// retrieve the map and return the collection of V
Map, V> map = (Map, V>) PropertyDataFetcherHelper
- .getPropertyValue(propertyName, source, environment.getFieldType(), environment);
+ .getPropertyValue(propertyName, source, environment.getFieldType(), () -> environment);
return map.values();
};
}
@@ -452,7 +454,7 @@ protected static Object parseArgumentValue(Class> originalType, String argumen
* An implementation of a {@link PropertyDataFetcher} which returns a formatted number.
*/
@SuppressWarnings("rawtypes")
- static class NumberFormattingDataFetcher extends PropertyDataFetcher {
+ static class NumberFormattingDataFetcher extends PropertyDataFetcher