dd-trace-java
dd-trace-java copied to clipboard
Using completedStage in GraphQL results in an error
If you use CompletableFuture.completedFuture
, there is no problem.
Or, No problems occur when DataDogAgent is not loaded by javaagent.
class Test {
fun test(
id: Long,
env: DataFetchingEnvironment,
): CompletionStage<DataFetcherResult<Test>> {
return CompletableFuture.completedStage(
DataFetcherResult.newResult<Test>()
.data(Test())
.localContext(TestLocalContext(id))
.build(),
)
}
}
Caused by: java.lang.UnsupportedOperationException
at java.base/java.util.concurrent.CompletableFuture$MinimalStage.isDone(CompletableFuture.java:2926)
at datadog.trace.instrumentation.graphqljava.InstrumentedDataFetcher.get(InstrumentedDataFetcher.java:59)
at graphql.execution.ExecutionStrategy.invokeDataFetcher(ExecutionStrategy.java:311)
at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:287)
at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:213)
at graphql.execution.AsyncExecutionStrategy.execute(AsyncExecutionStrategy.java:55)
at graphql.execution.ExecutionStrategy.completeValueForObject(ExecutionStrategy.java:702)
at graphql.execution.ExecutionStrategy.completeValue(ExecutionStrategy.java:484)
at graphql.execution.ExecutionStrategy.completeField(ExecutionStrategy.java:435)
at graphql.execution.ExecutionStrategy.lambda$resolveFieldWithInfo$1(ExecutionStrategy.java:215)
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1773)
Version
dd-java-agentt: 1.24.2 dd-trace-api: 1.24.2 graphql-java: 21.3 kotlin: 1.9.21
java --version
openjdk 17.0.9 2023-10-17 LTS
OpenJDK Runtime Environment Corretto-17.0.9.8.1 (build 17.0.9+8-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.9.8.1 (build 17.0.9+8-LTS, mixed mode, sharing)
completedStage
returns MinimalStage
.
public static <U> CompletionStage<U> completedStage(U value) {
return new MinimalStage<U>((value == null) ? NIL : value);
}
isDone
is not supported.
/**
* A subclass that just throws UOE for most non-CompletionStage methods.
*/
static final class MinimalStage<T> extends CompletableFuture<T> {
/* ~~ */
@Override public boolean isDone() {
throw new UnsupportedOperationException(); }
}
https://github.com/DataDog/dd-trace-java/blob/0f2d96f0b4b00ee1b1eaf28c858a8db1007fd9bc/dd-java-agent/instrumentation/graphql-java-14.0/src/main/java/datadog/trace/instrumentation/graphqljava/InstrumentedDataFetcher.java#L59
Adding a MinimalStage if-else seems like a good..
Thanks for the details about your issue @matsudamper !
It looks like your application is using graphql-java 21 which has recently upgraded from Java 8 to Java 11. MinimalStage
does not exist as a feature of CompletableFuture
until Java 9.
Because our instrumentation for graphql is based on graphql-java 14 and Java 8, we did not implement any handling of MinimalStage
.
This will require us to implement additional support for handling MinimalStage
for CompletableFuture
and as a result this will be handled as a feature request.