Skip to content

Commit 32ed3e9

Browse files
committed
Do not rewrap CompletionException in DataFetcher instrumentation
This commit ensures that, when an instrumented DataFetcher returns a `CompletionException`, we do not re-wrap it with the same exception type. This aligns with the behavior enforced in the JDK `CompletableFuture`. Fixes gh-780
1 parent 1032f99 commit 32ed3e9

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,15 @@ public DataFetcher<?> instrumentDataFetcher(DataFetcher<?> dataFetcher,
147147
return completion.handle((result, error) -> {
148148
observationContext.setValue(result);
149149
if (error != null) {
150-
dataFetcherObservation.error(error);
151-
dataFetcherObservation.stop();
152-
throw new CompletionException(error);
150+
if (error instanceof CompletionException completionException) {
151+
dataFetcherObservation.error(error.getCause());
152+
dataFetcherObservation.stop();
153+
throw completionException;
154+
} else {
155+
dataFetcherObservation.error(error);
156+
dataFetcherObservation.stop();
157+
throw new CompletionException(error);
158+
}
153159
}
154160
dataFetcherObservation.stop();
155161
return result;

spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import reactor.core.publisher.Mono;
3838

3939
import java.util.concurrent.CompletableFuture;
40+
import java.util.concurrent.CompletionException;
4041
import java.util.stream.Stream;
4142

4243
import static org.assertj.core.api.Assertions.assertThat;
@@ -168,8 +169,7 @@ void instrumentGraphQlRequestWhenDataFetchingFailure(DataFetcher<?> dataFetcher)
168169
.errorType(ErrorType.BAD_REQUEST).build());
169170
Mono<ExecutionGraphQlResponse> responseMono = graphQlSetup
170171
.exceptionResolver(resolver)
171-
.queryFetcher("bookById", env ->
172-
CompletableFuture.failedStage(new IllegalStateException("book fetching failure")))
172+
.queryFetcher("bookById", dataFetcher)
173173
.toGraphQlService()
174174
.execute(document);
175175
ResponseHelper response = ResponseHelper.forResponse(responseMono);
@@ -190,13 +190,14 @@ void instrumentGraphQlRequestWhenDataFetchingFailure(DataFetcher<?> dataFetcher)
190190
}
191191

192192
static Stream<Arguments> failureDataFetchers() {
193-
DataFetcher<Book> bookDataFetcher = environment -> {
194-
throw new IllegalStateException("book fetching failure");
195-
};
196193
return Stream.of(
197-
Arguments.of(bookDataFetcher),
194+
Arguments.of((DataFetcher<?>) environment -> {
195+
throw new IllegalStateException("book fetching failure");
196+
}),
197+
Arguments.of((DataFetcher<?>) environment ->
198+
CompletableFuture.failedStage(new IllegalStateException("book fetching failure"))),
198199
Arguments.of((DataFetcher<?>) environment ->
199-
CompletableFuture.failedStage(new IllegalStateException("book fetching failure")))
200+
CompletableFuture.failedStage(new CompletionException(new IllegalStateException("book fetching failure"))))
200201
);
201202
}
202203

0 commit comments

Comments
 (0)