Handle early GraphQLExceptions in ExecutionGraphQlService
Prior to this commit, the `ExecutionGraphQlService` would throw `GrahphQLException` instances if errors happen early in the process, for example in some cases of document parsing/validation. Such exception would be thrown directly and not reflected in the GraphQL response if those are `GraphQLError`. This commit ensures that a fallback GraphQL response is created in this case and that it contains the relevant `GraphQLError` information. Fixes gh-1118
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,8 +22,11 @@ import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.GraphQL;
|
||||
import graphql.GraphQLContext;
|
||||
import graphql.GraphQLError;
|
||||
import graphql.GraphQLException;
|
||||
import graphql.execution.ExecutionIdProvider;
|
||||
import graphql.execution.instrumentation.dataloader.EmptyDataLoaderRegistryInstance;
|
||||
import io.micrometer.context.ContextSnapshotFactory;
|
||||
@@ -102,6 +105,12 @@ public class DefaultExecutionGraphQlService implements ExecutionGraphQlService {
|
||||
ExecutionInput executionInputToUse = registerDataLoaders(executionInput);
|
||||
|
||||
return Mono.fromFuture(this.graphQlSource.graphQl().executeAsync(executionInputToUse))
|
||||
.onErrorResume(GraphQLException.class, (exception) -> {
|
||||
if (exception instanceof GraphQLError graphQLError) {
|
||||
return Mono.just(ExecutionResult.newExecutionResult().addError(graphQLError).build());
|
||||
}
|
||||
return Mono.error(exception);
|
||||
})
|
||||
.map((result) -> new DefaultExecutionGraphQlResponse(executionInputToUse, result));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.graphql.execution;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import graphql.ErrorType;
|
||||
import org.dataloader.DataLoaderRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
@@ -28,6 +29,7 @@ import org.springframework.graphql.ExecutionGraphQlRequest;
|
||||
import org.springframework.graphql.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.GraphQlSetup;
|
||||
import org.springframework.graphql.TestExecutionRequest;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlRequest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -35,7 +37,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Unit tests for {@link DefaultExecutionGraphQlService}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.2.4
|
||||
*/
|
||||
public class DefaultExecutionGraphQlServiceTests {
|
||||
|
||||
@@ -64,4 +65,18 @@ public class DefaultExecutionGraphQlServiceTests {
|
||||
assertThat(dataLoaderRegistry.getDataLoaders()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleGraphQlErrors() {
|
||||
GraphQlSource graphQlSource = GraphQlSetup.schemaContent("type Query { greeting: String }")
|
||||
.queryFetcher("greeting", (env) -> "hi")
|
||||
.toGraphQlSource();
|
||||
DefaultExecutionGraphQlService graphQlService = new DefaultExecutionGraphQlService(graphQlSource);
|
||||
|
||||
ExecutionGraphQlRequest request = new DefaultExecutionGraphQlRequest("{ greeting }", "unknown",
|
||||
null, null, "uniqueId", null);
|
||||
ExecutionGraphQlResponse response = graphQlService.execute(request).block();
|
||||
assertThat(response.getExecutionResult().getErrors()).singleElement()
|
||||
.hasFieldOrPropertyWithValue("errorType", ErrorType.ValidationError);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user