Skip to content

Commit e27bf54

Browse files
committed
Merge branch 'master' into infer-nullity-3
2 parents de00e30 + 6c2cdb0 commit e27bf54

30 files changed

+2140
-257
lines changed

.github/workflows/master.yml

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
gradle-argument: [ 'assemble && ./gradlew check -x test','testWithJava11', 'testWithJava17', 'test -x testWithJava11 -x testWithJava17' ]
14+
gradle-argument: [ 'assemble && ./gradlew check -x test','testWithJava11', 'testWithJava17','testWithJava21', 'test -x testWithJava11 -x testWithJava17 -x testWithJava21' ]
1515
steps:
1616
- uses: actions/checkout@v6
1717
- uses: gradle/actions/wrapper-validation@v5
18-
- name: Set up JDK 21
18+
- name: Set up JDK 25
1919
uses: actions/setup-java@v5
2020
with:
21-
java-version: '21'
21+
java-version: '25'
2222
distribution: 'corretto'
2323
- name: build and test
2424
run: ./gradlew ${{matrix.gradle-argument}} --info --stacktrace
@@ -30,6 +30,19 @@ jobs:
3030
**/build/test-results/test/TEST-*.xml
3131
**/build/test-results/testWithJava11/TEST-*.xml
3232
**/build/test-results/testWithJava17/TEST-*.xml
33+
**/build/test-results/testWithJava21/TEST-*.xml
34+
javadoc:
35+
runs-on: ubuntu-latest
36+
steps:
37+
- uses: actions/checkout@v6
38+
- uses: gradle/actions/wrapper-validation@v5
39+
- name: Set up JDK 25
40+
uses: actions/setup-java@v5
41+
with:
42+
java-version: '25'
43+
distribution: 'corretto'
44+
- name: Verify Javadoc
45+
run: ./gradlew javadoc --info --stacktrace
3346
publishToMavenCentral:
3447
needs: buildAndTest
3548
runs-on: ubuntu-latest
@@ -43,10 +56,10 @@ jobs:
4356
steps:
4457
- uses: actions/checkout@v6
4558
- uses: gradle/actions/wrapper-validation@v5
46-
- name: Set up JDK 21
59+
- name: Set up JDK 25
4760
uses: actions/setup-java@v5
4861
with:
49-
java-version: '21'
62+
java-version: '25'
5063
distribution: 'corretto'
5164
- name: publishToMavenCentral
5265
run: ./gradlew assemble && ./gradlew check -x test -x testng --info && ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -x check --info --stacktrace

.github/workflows/pull_request.yml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ jobs:
2020
runs-on: ubuntu-latest
2121
strategy:
2222
matrix:
23-
gradle-argument: [ 'assemble && ./gradlew check -x test','testWithJava11', 'testWithJava17', 'test -x testWithJava11 -x testWithJava17' ]
23+
gradle-argument: [ 'assemble && ./gradlew check -x test','testWithJava11', 'testWithJava17','testWithJava21', 'test -x testWithJava11 -x testWithJava17 -x testWithJava21' ]
2424
steps:
2525
- uses: actions/checkout@v6
2626
- uses: gradle/actions/wrapper-validation@v5
27-
- name: Set up JDK 21
27+
- name: Set up JDK 25
2828
uses: actions/setup-java@v5
2929
with:
30-
java-version: '21'
30+
java-version: '25'
3131
distribution: 'corretto'
3232
- name: build and test
3333
run: ./gradlew ${{matrix.gradle-argument}} --info --stacktrace
@@ -39,3 +39,16 @@ jobs:
3939
**/build/test-results/test/TEST-*.xml
4040
**/build/test-results/testWithJava11/TEST-*.xml
4141
**/build/test-results/testWithJava17/TEST-*.xml
42+
**/build/test-results/testWithJava21/TEST-*.xml
43+
javadoc:
44+
runs-on: ubuntu-latest
45+
steps:
46+
- uses: actions/checkout@v6
47+
- uses: gradle/actions/wrapper-validation@v5
48+
- name: Set up JDK 25
49+
uses: actions/setup-java@v5
50+
with:
51+
java-version: '25'
52+
distribution: 'corretto'
53+
- name: Verify Javadoc
54+
run: ./gradlew javadoc --info --stacktrace

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ jobs:
2121
steps:
2222
- uses: actions/checkout@v6
2323
- uses: gradle/actions/wrapper-validation@v5
24-
- name: Set up JDK 21
24+
- name: Set up JDK 25
2525
uses: actions/setup-java@v5
2626
with:
27-
java-version: '21'
27+
java-version: '25'
2828
distribution: 'corretto'
2929
- name: build test and publish
3030
run: ./gradlew assemble && ./gradlew check --info && ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -x check --info --stacktrace

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ docs/_build/
1515
\.settings/
1616
/.nb-gradle/
1717
gen
18-
.DS_Store
18+
.DS_Store
19+
.vscode

AGENTS.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# AI Agent Context for graphql-java
2+
3+
This file provides context for AI assistants working with this codebase.
4+
5+
## Test Execution
6+
7+
When running tests, exclude the Java version-specific test tasks to avoid failures:
8+
9+
```bash
10+
./gradlew test -x testWithJava21 -x testWithJava17 -x testWithJava11 -x testng
11+
```

build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,12 @@ tasks.withType(Test) {
357357
}
358358
}
359359

360+
tasks.register('testWithJava21', Test) {
361+
javaLauncher = javaToolchains.launcherFor {
362+
languageVersion = JavaLanguageVersion.of(21)
363+
}
364+
}
365+
360366
tasks.register('testWithJava17', Test) {
361367
javaLauncher = javaToolchains.launcherFor {
362368
languageVersion = JavaLanguageVersion.of(17)
@@ -385,6 +391,7 @@ tasks.register('testWithJava11', Test) {
385391

386392
}
387393

394+
test.dependsOn testWithJava21
388395
test.dependsOn testWithJava17
389396
test.dependsOn testWithJava11
390397

src/main/java/graphql/execution/ExecutionStrategy.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -489,12 +489,17 @@ private Object fetchField(GraphQLFieldDefinition fieldDef, ExecutionContext exec
489489

490490
CompletableFuture<CompletableFuture<Object>> handleCF = engineRunningState.handle(fetchedValue, (result, exception) -> {
491491
// because we added an artificial CF, we need to unwrap the exception
492-
fetchCtx.onCompleted(result, exception);
493-
exception = engineRunningState.possibleCancellation(exception);
494-
495-
if (exception != null) {
496-
return handleFetchingException(dataFetchingEnvironment.get(), parameters, exception);
492+
Throwable possibleWrappedException = engineRunningState.possibleCancellation(exception);
493+
494+
if (possibleWrappedException != null) {
495+
CompletableFuture<DataFetcherResult<Object>> handledExceptionResult = handleFetchingException(dataFetchingEnvironment.get(), parameters, possibleWrappedException);
496+
return handledExceptionResult.thenApply( handledResult -> {
497+
fetchCtx.onExceptionHandled(handledResult);
498+
fetchCtx.onCompleted(result, exception);
499+
return handledResult;
500+
});
497501
} else {
502+
fetchCtx.onCompleted(result, exception);
498503
// we can simply return the fetched value CF and avoid a allocation
499504
return fetchedValue;
500505
}
@@ -578,7 +583,7 @@ private void addExtensionsIfPresent(ExecutionContext executionContext, DataFetch
578583
}
579584
}
580585

581-
protected <T> CompletableFuture<T> handleFetchingException(
586+
protected <T> CompletableFuture<DataFetcherResult<T>> handleFetchingException(
582587
DataFetchingEnvironment environment,
583588
ExecutionStrategyParameters parameters,
584589
Throwable e
@@ -599,10 +604,10 @@ protected <T> CompletableFuture<T> handleFetchingException(
599604
}
600605
}
601606

602-
private <T> CompletableFuture<T> asyncHandleException(DataFetcherExceptionHandler handler, DataFetcherExceptionHandlerParameters handlerParameters) {
607+
private <T> CompletableFuture<DataFetcherResult<T>> asyncHandleException(DataFetcherExceptionHandler handler, DataFetcherExceptionHandlerParameters handlerParameters) {
603608
//noinspection unchecked
604609
return handler.handleException(handlerParameters).thenApply(
605-
handlerResult -> (T) DataFetcherResult.newResult().errors(handlerResult.getErrors()).build()
610+
handlerResult -> (DataFetcherResult<T>) DataFetcherResult.newResult().errors(handlerResult.getErrors()).build()
606611
);
607612
}
608613

src/main/java/graphql/execution/instrumentation/ChainedInstrumentation.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import graphql.ExperimentalApi;
77
import graphql.PublicApi;
88
import graphql.execution.Async;
9+
import graphql.execution.DataFetcherResult;
910
import graphql.execution.ExecutionContext;
1011
import graphql.execution.FieldValueInfo;
1112
import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters;
@@ -380,6 +381,11 @@ public void onFetchedValue(Object fetchedValue) {
380381
contexts.forEach(context -> context.onFetchedValue(fetchedValue));
381382
}
382383

384+
@Override
385+
public void onExceptionHandled(DataFetcherResult<Object> dataFetcherResult) {
386+
contexts.forEach(context -> context.onExceptionHandled(dataFetcherResult));
387+
}
388+
383389
@Override
384390
public void onCompleted(Object result, Throwable t) {
385391
contexts.forEach(context -> context.onCompleted(result, t));

src/main/java/graphql/execution/instrumentation/FieldFetchingInstrumentationContext.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import graphql.Internal;
44
import graphql.PublicSpi;
5+
import graphql.execution.DataFetcherResult;
56
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters;
67
import org.jspecify.annotations.NonNull;
78
import org.jspecify.annotations.Nullable;
@@ -26,6 +27,15 @@ public interface FieldFetchingInstrumentationContext extends InstrumentationCont
2627
default void onFetchedValue(Object fetchedValue) {
2728
}
2829

30+
/**
31+
* This is called back after any {@link graphql.execution.DataFetcherExceptionHandler}) has run on any exception raised
32+
* during a {@link graphql.schema.DataFetcher} invocation. This allows to see the final {@link DataFetcherResult}
33+
* that will be used when performing the complete step.
34+
* @param dataFetcherResult the final {@link DataFetcherResult} after the exception handler has run
35+
*/
36+
default void onExceptionHandled(DataFetcherResult<Object> dataFetcherResult) {
37+
}
38+
2939
@Internal
3040
FieldFetchingInstrumentationContext NOOP = new FieldFetchingInstrumentationContext() {
3141
@Override

src/main/java/graphql/language/NodeUtil.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,5 +138,10 @@ ImmutableList<Directive> getDirectives(String directiveName) {
138138
boolean hasDirective(String directiveName) {
139139
return directivesByName.containsKey(directiveName);
140140
}
141+
142+
@Override
143+
public String toString() {
144+
return directives.toString();
145+
}
141146
}
142147
}

0 commit comments

Comments
 (0)